【模板】可持久化Treap

洛谷3835

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstdlib>
 4 #define ls (a[u].l)
 5 #define rs (a[u].r)
 6 #define R (root[Ver])
 7 #define update(u) (a[u].size=a[a[u].l].size+a[a[u].r].size+1)
 8 #define copy(x) (a[++tot]=a[x],a[x=tot].ver=Ver)
 9 using namespace std;
10 int Ver,ver,Opt,Val,n,x,y,z,tot,root[500010];
11 struct treap{int l,r,val,rnd,size,ver;}a[10000000];
12 inline void read(int &k){
13     k=0; int f=1; char c=getchar();
14     while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar();
15     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
16     k*=f;
17 }
18 inline void put(int x){
19     if(x<0) putchar('-'),x=-x;
20     char s[1000]; int k=0,y=0;
21     while(x>0){
22         y=x; x/=10;
23         s[++k]=y-x*10+48;
24     }
25     for (int i=k;i>=1;i--) putchar(s[i]);
26     puts(y?"":"0");
27 }
28 inline void newnode(int val){a[++tot]=(treap){0,0,val,rand(),1,Ver};}
29 void split(int u,int k,int &x,int &y){
30     if(!k){x=0; y=u; return;}
31     if(a[u].size==k){x=u; y=0; return;}
32     if (a[u].ver<Ver) copy(u);
33     if(a[ls].size>=k) split(ls,k,x,ls),y=u;
34     else split(rs,k-a[ls].size-1,rs,y),x=u;
35     update(u);
36 }
37 int merge(int x,int y){//x较小树,y较大树 
38     if ((!x)||(!y)) return x+y;
39     if(a[x].rnd<a[y].rnd){if (a[x].ver<Ver) copy(x); a[x].r=merge(a[x].r,y); update(x); return x;}
40     else{if (a[y].ver<Ver) copy(y); a[y].l=merge(x,a[y].l); update(y); return y;}    
41 }
42 int qrank(int u,int val){
43     if(!u) return 0;
44     return a[u].val>=val?qrank(ls,val):qrank(rs,val)+a[ls].size+1;
45 }
46 int qval(int u,int rank){
47     if(a[ls].size+1==rank) return a[u].val;
48     return a[ls].size>=rank?qval(ls,rank):qval(rs,rank-a[ls].size-1);
49 }
50 int main(){
51     srand(20020705); a[root[0]=tot=1]=(treap){0,0,1<<30,-1,1,0};
52     read(n);
53     for(Ver=1;Ver<=n;Ver++){
54         read(ver); R=root[ver];
55         read(Opt); read(Val);
56         if(Opt==1){split(R,qrank(R,Val),x,y); newnode(Val); R=merge(merge(x,tot),y);}//插入 
57         if(Opt==2){//删除
58             int tmp=qrank(R,Val);
59             if (qval(R,tmp+1)!=Val) continue;
60             split(R,tmp,x,y); split(y,1,z,y); R=merge(x,y);
61         }
62         if(Opt==3) put(qrank(R,Val)+1);//求x的排名
63         if(Opt==4) put(qval(R,Val));//求排名为x的数
64         if(Opt==5){//求x的前驱
65             int tmp=qrank(R,Val);
66             if(tmp) put(qval(R,tmp)); else puts("-2147483647");
67         }
68         if(Opt==6){//求x的后继
69             int tmp=qrank(R,Val+1);
70             if(tmp<a[R].size) put(qval(R,tmp+1)); else puts("2147483647");
71         }
72     }
73     return 0;
74 }
View Code

 

posted @ 2017-12-08 20:43  Driver_Lao  阅读(164)  评论(0编辑  收藏  举报