SplayTree--BZOJ1500

来源:互联网 发布:linux关闭oracle服务 编辑:程序博客网 时间:2024/06/16 05:15

这里写图片描述
这是一个Splay模板题,适合用来连代码能力
对于翻转操作,可以加入一个布尔值标记flip,对于最大连续子段和,可以维护三个标记:maxl,maxr,maxs分别表示最大前缀和,最大后缀和,最大子段和。具体的更新函数可以参照线段树。特别要注意标记的下推,更新标记时要考虑全面。

#include<cstdio>#include<cstring>#include<algorithm>#define INF -1e9#define maxn 500006using namespace std;struct node{    node* ch[2];    int key,num,sum,maxs,maxl,maxr,tag,flip;    void add_tag(int k){        key=tag=k;sum=k*num;        if(k>0)maxs=maxl=maxr=k*num;          else maxs=maxl=maxr=k;    }    void add_flip(){        swap(maxl,maxr);swap(ch[0],ch[1]);flip^=1;    }    void pushdown(){        if(tag!=INF)ch[0]->add_tag(tag),ch[1]->add_tag(tag),tag=INF;        if(flip)ch[0]->add_flip(),ch[1]->add_flip(),flip=0;    }    int maintain(){        sum=ch[0]->sum+key+ch[1]->sum;num=ch[0]->num+1+ch[1]->num;        maxl=max(max(ch[0]->maxl,ch[0]->sum+key),ch[0]->sum+key+ch[1]->maxl);        maxr=max(max(ch[1]->maxr,ch[1]->sum+key),ch[1]->sum+key+ch[0]->maxr);        maxs=max(key,max(ch[0]->maxr+key+ch[1]->maxl,max(max(ch[0]->maxs,ch[1]->maxs),max(ch[0]->maxr+key,key+ch[1]->maxl))));    }    int cmp(int &k){        if(k<ch[0]->num+1)return 0;        if(k==ch[0]->num+1)return -1;        k-=ch[0]->num+1;return 1;    }}nul;typedef node* pnode;pnode rt,null=&nul;pnode newnode(int key){    pnode p=new node;p->key=p->sum=p->maxs=p->maxl=p->maxr=key;p->ch[0]=p->ch[1]=null;    p->tag=INF;p->flip=0;p->num=1;    return p;}void rot(pnode &p,int d){    pnode k=p->ch[d^1];p->ch[d^1]=k->ch[d];k->ch[d]=p;    p->maintain();k->maintain();p=k;}void splay(pnode &p,int k){    p->pushdown();    int d1=p->cmp(k);    if(d1!=-1){        p->ch[d1]->pushdown();int d2=p->ch[d1]->cmp(k);        if(d2!=-1){            splay(p->ch[d1]->ch[d2],k);            if(d1==d2)rot(p,d1^1);                 else rot(p->ch[d1],d2^1);        }        rot(p,d1^1);    }}void del(pnode p){    if(p==null)return;    del(p->ch[0]);del(p->ch[1]);    delete p;}pnode build(int l,int r,int*arr){    if(l>r)return null;    int mid=(l+r)/2;    pnode p=newnode(*(arr+mid));    p->ch[0]=build(l,mid-1,arr);p->ch[1]=build(mid+1,r,arr);    p->maintain();    return p;}void print_splay(pnode p){    if(p==null)return;    p->pushdown();    print_splay(p->ch[0]);//  printf("%d ",p->key);    print_splay(p->ch[1]);}int _read(){    char ch=getchar();int p,sum=0;    while((ch!='-')&&(!(ch>='0'&&ch<='9')))ch=getchar();    if(ch=='-')p=-1,ch=getchar();else p=1;    while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=getchar();    return sum*p;}int n,m,c[maxn];int main(){    null->ch[0]=null->ch[1]=null;null->num=null->flip=null->sum=null->key=0;null->tag=null->maxl=null->maxr=null->maxs=INF;    freopen("sequence.in","r",stdin);    freopen("sequence.out","w",stdout);    n=_read();m=_read();    for(int i=1;i<=n;i++)c[i]=_read();c[n+1]=0;    rt=build(0,n+1,c);    for(int t=1;t<=m;t++){        char s[30];scanf("%s",s);        if(s[0]=='I'){            int x=_read(),tot=_read();x++;            for(int i=1;i<=tot;i++)c[i]=_read();            splay(rt,x);splay(rt->ch[1],1);            rt->ch[1]->ch[0]=build(1,tot,c);            rt->ch[1]->maintain();rt->maintain();        }else        if(s[0]=='D'){            int x=_read(),tot=_read();x++;            splay(rt,x-1);splay(rt->ch[1],tot+1);            del(rt->ch[1]->ch[0]);rt->ch[1]->ch[0]=null;            rt->ch[1]->maintain();rt->maintain();        }else        if(s[2]=='K'){            int x=_read(),tot=_read(),y=_read();x++;            splay(rt,x-1);splay(rt->ch[1],tot+1);            rt->ch[1]->ch[0]->add_tag(y);        }else        if(s[0]=='R'){            int x=_read(),tot=_read();x++;            splay(rt,x-1);splay(rt->ch[1],tot+1);            rt->ch[1]->ch[0]->add_flip();        }else        if(s[0]=='G'){            int x=_read(),tot=_read();x++;            splay(rt,x-1);splay(rt->ch[1],tot+1);            printf("%d\n",rt->ch[1]->ch[0]->sum);        }else{            splay(rt,1);splay(rt->ch[1],rt->ch[1]->num);            printf("%d\n",rt->ch[1]->ch[0]->maxs);        }//      print_splay(rt);    }    return 0;}
0 0
原创粉丝点击