treap-[NOI2005]维护数列

swap的标记要注意,打标记时先要更新根节点

#include<bits/stdc++.h>
using namespace std;
const int MAXA=4050000;
const int MAXN=5e8;
int val[MAXA],s[MAXA][2],su[MAXA][2],sum[MAXA],ans[MAXA],vflag[MAXA],tag[MAXA],siz[MAXA];
void update(int x){
    if(x==0) return ;
    siz[x]=siz[s[x][0]]+siz[s[x][1]]+1;
    sum[x]=val[x]+sum[s[x][0]]+sum[s[x][1]];
    su[x][0]=max(su[s[x][1]][0],sum[s[x][1]]+val[x]+max(0,su[s[x][0]][0]));
    su[x][1]=max(su[s[x][0]][1],sum[s[x][0]]+val[x]+max(0,su[s[x][1]][1]));
    ans[x]=max(max(ans[s[x][0]],ans[s[x][1]]),max(su[s[x][0]][0],0)+val[x]+max(su[s[x][1]][1],0));
}
void changevflag(int x,int y){
    if(!x) return ;
    vflag[x]=y;
    sum[x]=siz[x]*y;
    val[x]=y;
    if(y>0) su[x][0]=su[x][1]=ans[x]=sum[x];
    else su[x][0]=su[x][1]=ans[x]=y;
}
void tagp(int x){
	swap(s[x][0],s[x][1]);
	swap(su[x][0],su[x][1]);
}
void pushdown(int x){
    if(vflag[x]!=MAXN){
	changevflag(s[x][0],vflag[x]);
	changevflag(s[x][1],vflag[x]);
	vflag[x]=MAXN;
    }
    if(tag[x]){
	if(s[x][0]) tag[s[x][0]]^=1,tagp(s[x][0]);
	if(s[x][1]) tag[s[x][1]]^=1,tagp(s[x][1]);
	tag[x]=0;
    }
}
void make(int &n,int l,int r){
    if(l>r) return ;
    if(l==r){
	n=l;
	update(n);
	return;
    }
    n=(l+r)>>1;
    make(s[n][0],l,n-1);make(s[n][1],n+1,r);
    update(n);
}
int merge(int root1,int root2){
    if(!(root1+root2)) return 0;
    if(rand()%(siz[root1]+siz[root2])<siz[root1]){
	pushdown(root1);
	s[root1][1]=merge(s[root1][1],root2);
	update(root1);
	return root1;
    }else{
	pushdown(root2);
	s[root2][0]=merge(root1,s[root2][0]);
	update(root2);
	return root2;
    }
}
pair<int,int> spilt(int root,int cut){
    pushdown(root);
    if(cut==0) return make_pair(0,root);
    if(cut<=siz[s[root][0]]){
	pair<int,int> nxt=spilt(s[root][0],cut);
	s[root][0]=nxt.second;
	update(root);
	return make_pair(nxt.first,root);
    }
    cut-=siz[s[root][0]]+1;
    if(cut==0){
	int y=s[root][1];
	s[root][1]=0;
	update(root);
	return make_pair(root,y);
    }
    pair<int,int> nxt=spilt(s[root][1],cut);
    s[root][1]=nxt.first;
    update(root);
    return make_pair(root,nxt.second);
}
void printt(int x){
    if(!x) return ;
    pushdown(x);
    printt(s[x][0]);
    printf("%d ",val[x]);
    printt(s[x][1]);
}
void print(int x){
    if(!x) return ;
    pushdown(x);
    printf("%d %d %d %d %d
",val[x],val[s[x][0]],val[s[x][1]],sum[x],ans[x]);
    print(s[x][0]);print(s[x][1]);
}
int main(){
    char ss[1000];
    int x,m,n,t,y,root;
    siz[0]=0; sum[0]=0; su[0][0]=su[0][1]=ans[0]=-MAXN-1;
    scanf("%d%d",&n,&t);
    for(int i=1;i<=n;i++) scanf("%d",&val[i]);
    for(int i=0;i<=n;i++) vflag[i]=MAXN;
    make(root,1,n);
    //print(root);
    //printf("
");
    while(t--){
	scanf("%s",ss);
	if(ss[2]=='S'){
	    scanf("%d",&x);
	    int ro;
	    pair<int,int> ro1=spilt(root,x);
	    scanf("%d",&m);
	    for(int i=1;i<=m;i++)
		scanf("%d",&val[i+n]),vflag[i+n]=MAXN;
	    make(ro,n+1,n+m);
	    n+=m;
	    root=merge(merge(ro1.first,ro),ro1.second);
	}
	if(ss[2]=='L'){
	    scanf("%d%d",&x,&m);
	    pair<int,int>ro1=spilt(root,x-1);
	    pair<int,int>ro2=spilt(ro1.second,m);
	    root=merge(ro1.first,ro2.second);
	    //printt(root);
	    //printf("
");
	}
	if(ss[2]=='K'){
	    scanf("%d%d%d",&x,&m,&y);
	    pair<int,int>ro1=spilt(root,x-1);
	    pair<int,int>ro2=spilt(ro1.second,m);
	    changevflag(ro2.first,y);
	    root=merge(merge(ro1.first,ro2.first),ro2.second);
	}
	if(ss[2]=='V'){
	    scanf("%d%d",&x,&m);
	    pair<int,int> ro1=spilt(root,x-1);
	    pair<int,int>ro2=spilt(ro1.second,m);
	    //printt(ro2.first);
	    //printf("
");
	    tag[ro2.first]^=1;
	    //swap(su[ro2.first][0],su[ro2.first][1]);
	    //swap(s[ro2.first][0],s[ro2.first][1]);
	    tagp(ro2.first);
	    //printt(ro2.first);
	    //printf("
");
	    root=merge(merge(ro1.first,ro2.first),ro2.second);
	    //printt(root);
	    //printf("
");
	}
	if(ss[2]=='T'){
	    scanf("%d%d",&x,&m);
	    pair<int,int> ro1=spilt(root,x-1);
	    pair<int,int>ro2=spilt(ro1.second,m);
	    printf("%d
",sum[ro2.first]);
	    root=merge(merge(ro1.first,ro2.first),ro2.second);
	}
	if(ss[2]=='X'){
	    printf("%d
",ans[root]);
	}
    }
}
原文地址:https://www.cnblogs.com/ac_forever/p/11185187.html