您的位置:首页 > 其它

BZOJ 1251 序列终结者

2015-12-22 21:42 375 查看
AC通道:http://www.lydsy.com/JudgeOnline/problem.php?id=1251

这题就是充分利用文艺平衡树那题留下的心理阴影啊...

总之,我们已经知道平衡树可以像线段树一样操作[非递归线段树的感觉...],不过平衡树支持神奇的翻转操作...[这个见文艺平衡树]

然后就是tag的下传和向上更新了...一定要注意细节啊~什么左子树右子树是不是为空,还是要仔细看一看的啦...

#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

inline int in(){
int x=0,f=1;char ch=getchar();
while((ch>'9' || ch<'0') && ch!='-') ch=getchar();
if(ch=='-') f=-1,ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}

const int maxn=100010;

struct Node{
int Mx,sz,dt;
int l,r,f;
int ad;
bool mk;

void trans(){swap(l,r);}
}s[maxn];

int rt,n,m;

void update(int x){
s[x].sz=s[s[x].l].sz+s[s[x].r].sz+1;

s[x].Mx=s[x].dt;
if(s[x].l) s[x].Mx=max(s[x].Mx,s[s[x].l].Mx);
if(s[x].r) s[x].Mx=max(s[x].Mx,s[s[x].r].Mx);
}

void push_down(int x){
if(s[x].mk){
s[x].trans();s[x].mk=0;
if(s[x].l) s[s[x].l].mk^=1;
if(s[x].r) s[s[x].r].mk^=1;
}
if(s[x].ad){
if(s[x].l) {s[s[x].l].ad+=s[x].ad;s[s[x].l].dt+=s[x].ad;s[s[x].l].Mx+=s[x].ad;}
if(s[x].r) {s[s[x].r].ad+=s[x].ad;s[s[x].r].dt+=s[x].ad;s[s[x].r].Mx+=s[x].ad;}
s[x].ad=0;
}
}

int build(int l,int r){
if(l>r) return 0;
int mid=(l+r)>>1;
s[mid].l=build(l,mid-1);
s[mid].r=build(mid+1,r);
update(mid);
if(s[mid].l) s[s[mid].l].f=mid;
if(s[mid].r) s[s[mid].r].f=mid;
return mid;
}

void zig(int x){
int y=s[x].f;

s[x].f=s[y].f;
if(s[y].f){
if(y==s[s[y].f].l) s[s[y].f].l=x;
else s[s[y].f].r=x;
}

s[y].l=s[x].r;
if(s[x].r) s[s[x].r].f=y;

s[x].r=y;s[y].f=x;

update(y),update(x);
}

void zag(int x){
int y=s[x].f;

s[x].f=s[y].f;
if(s[y].f){
if(y==s[s[y].f].l) s[s[y].f].l=x;
else s[s[y].f].r=x;
}

s[y].r=s[x].l;
if(s[x].l) s[s[x].l].f=y;

s[x].l=y;s[y].f=x;

update(y),update(x);
}

void Splay(int x,int gf){
int y;
while(s[x].f!=gf){
y=s[x].f;
if(s[y].f==gf){
if(x==s[y].l) zig(x);
else zag(x);
}
else{
int z=s[y].f;
if(y==s[z].l){
if(x==s[y].l) zig(y),zig(x);
else zag(x),zig(x);
}
else{
if(x==s[y].r) zag(y),zag(x);
else zig(x),zag(x);
}
}
}

if(!gf) rt=x;
}

int Find(int k){
int p=rt;
while(p){
push_down(p);
if(k<=s[s[p].l].sz) p=s[p].l;
else{
k-=s[s[p].l].sz;
if(k==1) return p;
k--;p=s[p].r;
}
}
}

void add(int L,int R,int k){
int a=Find(L),b=Find(R+2);
Splay(a,0);Splay(b,a);
s[s[b].l].ad+=k,s[s[b].l].dt+=k,s[s[b].l].Mx+=k;
}

void rev(int L,int R){
int a=Find(L),b=Find(R+2);
Splay(a,0);Splay(b,a);
s[s[b].l].mk^=1;
}

int ask(int L,int R){
int a=Find(L),b=Find(R+2);
Splay(a,0);Splay(b,a);
return s[s[b].l].Mx;
}

int main(){
#ifndef ONLINE_JUDGE
freopen("1512.in","r",stdin);
freopen("1512.out","w",stdout);
#endif

int ord,L,R,k;

n=in(),m=in();
rt=build(1,n+2);

while(m--){
ord=in();L=in(),R=in();
if(ord==1)
k=in(),add(L,R,k);
else if(ord==2)
rev(L,R);
else
printf("%d\n",ask(L,R));
}

return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: