bzoj1251: 序列终结者 fhqtreap写法

fhqtreap的速度果然很快 花了时间学了下指针写法

没有旋转 只有分裂以及合并操作 其实还是蛮好写的

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=50055;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m;
struct node{
    node *l,*r;
    int v,sz,rev,rnd,tag,mx;
    void init(){sz=1; rnd=rand();}
    void revs(){rev^=1; swap(l,r);}
    void add(int w){tag+=w; mx+=w; v+=w;}
    void up(){
        sz=1; mx=v;
        if(l) sz+=l->sz,mx=max(mx,l->mx);
        if(r) sz+=r->sz,mx=max(mx,r->mx);
    }
    void dn(){
        if(rev){
            if(l) l->revs();
            if(r) r->revs();
            rev=0;
        }
        if(tag){
            if(l) l->add(tag);
            if(r) r->add(tag);
            tag=0;
        }
    }
    void split(node*&lw,node*&rw,int k){
        if(!this){lw=0; rw=0; return ;}
        int ls=l?l->sz:0;
        dn();
        if(k<=ls){
            l->split(lw,l,k);
            rw=this;
        }
        else{
            r->split(r,rw,k-ls-1);
            lw=this;
        }
        up();
    }
}tr[M],*rt;
node* merge(node*a,node*b){
    if(!a) return b;
    if(!b) return a;
    if(a->rnd>b->rnd){
        a->dn();
        a->r=merge(a->r,b);
        a->up();
        return a;
    }{
        b->dn();
        b->l=merge(a,b->l);
        b->up();
        return b;
    }
}
int main()
{
    int k,w,l,r;
    n=read(); m=read();
    for(int i=1;i<=n;i++) tr[i].init(),rt=merge(rt,tr+i);
    while(m--){
        k=read();
        if(k==1){
            node *p1,*p2,*p3;
            l=read(); r=read(); w=read();
            rt->split(p2,p3,r);
            p2->split(p1,p2,l-1);
            p2->add(w);
            rt=merge(merge(p1,p2),p3);
        }
        else if(k==2){
            node *p1,*p2,*p3;
            l=read(); r=read();
            rt->split(p2,p3,r);
            p2->split(p1,p2,l-1);
            p2->revs();
            rt=merge(merge(p1,p2),p3);
        }
        else{
            node *p1,*p2,*p3;
            l=read(); r=read();
            rt->split(p2,p3,r);
            p2->split(p1,p2,l-1);
            printf("%d\n",p2->mx);
            rt=merge(merge(p1,p2),p3);
        }
    }
    return 0;
}
View Code

 

posted @ 2017-06-02 14:27  友人Aqwq  阅读(250)  评论(0编辑  收藏  举报