luoguP5055 【模板】可持久化文艺平衡树 可持久化非旋转treap

好题.

Code:

#include<bits/stdc++.h>
using namespace std;
#define setIO(s) freopen(s".in","r",stdin)    
namespace fhqtreap{
    #define maxn 20000000   
    #define ll long long 
    int tot,m,tr;
    int trash[maxn]; 
    int ls[maxn],rs[maxn],rev[maxn],val[maxn],sz[maxn],key[maxn];  
    int root[maxn]; 
    ll sumv[maxn];
    ll lastans;   
    void ini(){
        tr=0; 
        for(int i=1;i<1000000;++i) trash[++tr]=i; 
        tot=1000001; 
    }
    int newnode(){ 
        return tr?trash[tr--]:++tot; 
    }
    int cpy(int p){   
        int x=newnode();     
        sz[x]=sz[p],ls[x]=ls[p],rs[x]=rs[p]; 
        rev[x]=rev[p],val[x]=val[p],key[x]=key[p],sumv[x]=sumv[p]; 
        return x; 
    }
    void up(int x){
        sz[x]=sz[ls[x]]+sz[rs[x]]+1;
        sumv[x]=sumv[ls[x]]+sumv[rs[x]]+(long long)val[x]; 
    }
    int New(int v){
        int p=newnode(); 
        sz[p]=1,ls[p]=rs[p]=0,sumv[p]=val[p]=v,key[p]=rand(),rev[p]=0; 
        return p; 
    }
    void era(int x){
        sz[x]=ls[x]=rs[x]=rev[x]=val[x]=sumv[x]=key[x]=0; 
        trash[++tr]=x; 
    }
    void pd(int x){
        if(!x||!rev[x]) return;     
        if(rev[x]){
            swap(ls[x],rs[x]);
            if(ls[x]) ls[x]=cpy(ls[x]),rev[ls[x]]^=1;
            if(rs[x]) rs[x]=cpy(rs[x]),rev[rs[x]]^=1; 
            rev[x]=0; 
        }
    }
    void split(int x,int k,int &l,int &r){
        if(x){
            pd(x); 
            if(k<=sz[ls[x]]) {
                r=cpy(x);     
                split(ls[r],k,l,ls[r]);  
                up(r); 
            }
            else {
                l=cpy(x); 
                split(rs[l],k-sz[ls[l]]-1,rs[l],r);   
                up(l);  
            }
        }else l=r=0; 
    }
    int mg(int l,int r){
        if(l&&r){
            if(key[l]<key[r]) {
                pd(r),ls[r]=mg(l,ls[r]),up(r); 
                return r; 
            }else {
                pd(l),rs[l]=mg(rs[l],r),up(l); 
                return l; 
            }
        }else return l+r;     
    }         
    void ins(int &rt,int p,int v){
        int x,y; 
        split(rt,p,x,y);         
        rt=mg(mg(x,New(v)),y);  
    }
    void Del(int &rt,int p){      
        int x,y,z; 
        split(rt,p,x,y),split(x,p-1,x,z),era(z); 
        rt=mg(x,y); 
    }
    void Rev(int &rt,int L,int R){
        int x,y,z; 
        split(rt,R,x,y),split(x,L-1,x,z),rev[z]^=1; 
        rt=mg(mg(x,z),y); 
    }
    void Q(int &rt,int L,int R){
        int x,y,z; 
        split(rt,R,x,y),split(x,L-1,x,z), printf("%lld\n",(lastans=sumv[z])); 
        rt=mg(mg(x,z),y); 
    }
    int main(){
        ini();
        int n,a=0,b=0; 
        scanf("%d",&n); 
        for(int opt,v,i=1;i<=n;++i){
            scanf("%d%d",&v,&opt); 
            root[i]=root[v]; 
            scanf("%d",&a),a^=lastans; 
            if(opt!=2) scanf("%d",&b),b^=lastans; 
            if(opt==1) ins(root[i],a,b); 
            if(opt==2) Del(root[i],a); 
            if(opt==3) Rev(root[i],a,b); 
            if(opt==4) Q(root[i],a,b); 
        }
        return 0; 
    }
}; 
int main(){
    //setIO("input"); 
    fhqtreap::main(); 
    return 0; 
}

  

上一篇:[ActionScript 3.0] AS3.0 让一个视频无缝循环播放的一个偏方


下一篇:BZOJ 3435: [Wc2014]紫荆花之恋 【(替罪羊树式)"动态"点分治 + Treap】