题面:【模板】普通平衡树
代码:
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<cstdlib> 5 using namespace std; 6 inline int rd(){ 7 int x=0,f=1;char c=getchar(); 8 while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();} 9 while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} 10 return f*x; 11 } 12 const int maxn=(2e5)+50; 13 int N,chd[maxn][3],a,o,val[maxn],rt,x,y,z,g,pr[maxn],tot=0,siz[maxn]; 14 inline int New_node(int a){ 15 val[++tot]=a; 16 pr[tot]=rand(); 17 siz[tot]=1; 18 return tot; 19 } 20 inline void Pushup(int a){ 21 siz[a]=siz[chd[a][0]]+siz[chd[a][1]]+1; 22 return; 23 } 24 inline void Split(int now,int k,int &x,int &y){ 25 if(!now){x=y=0; return;} 26 if(val[now]<=k){ 27 x=now; 28 Split(chd[now][1],k,chd[now][1],y); 29 } 30 else{ 31 y=now; 32 Split(chd[now][0],k,x,chd[now][0]); 33 } 34 Pushup(now); 35 return; 36 } 37 inline int Merge(int a,int b){ 38 if(!a||!b)return (a+b); 39 if(pr[a]<pr[b]){ 40 chd[a][1]=Merge(chd[a][1],b); 41 Pushup(a); 42 return a; 43 } 44 else{ 45 chd[b][0]=Merge(a,chd[b][0]); 46 Pushup(b); 47 return b; 48 } 49 } 50 inline int Kth(int now,int k){ 51 while(now){ 52 if(k<=siz[chd[now][0]])now=chd[now][0]; 53 else if(k==siz[chd[now][0]]+1)return now; 54 else k=k-siz[chd[now][0]]-1,now=chd[now][1]; 55 } 56 return now; 57 } 58 int main(){ 59 srand(20030304); 60 N=rd(); 61 rt=0; 62 while(N--){ 63 o=rd();a=rd(); 64 if(o==1){ 65 Split(rt,a,x,y); 66 rt=Merge(Merge(x,New_node(a)),y); 67 } 68 else if(o==2){ 69 Split(rt,a,x,z); 70 Split(x,a-1,x,y); 71 rt=Merge(Merge(x,Merge(chd[y][0],chd[y][1])),z); 72 } 73 else if(o==3){ 74 Split(rt,a-1,x,y); 75 printf("%d\n",siz[x]+1); 76 rt=Merge(x,y); 77 } 78 else if(o==4){ 79 printf("%d\n",val[Kth(rt,a)]); 80 } 81 else if(o==5){ 82 Split(rt,a-1,x,y); 83 printf("%d\n",val[Kth(x,siz[x])]); 84 rt=Merge(x,y); 85 } 86 else{//o==6 87 Split(rt,a,x,y); 88 printf("%d\n",val[Kth(y,1)]); 89 rt=Merge(x,y); 90 } 91 } 92 return 0; 93 }
By:AlenaNuna