#include<iostream> #include<cstdio> #include<string> #include<cstring> #include<cstdlib> using namespace std; const int N = 100000 + 1100; const int INF = 0x3f3f3f3f; int son[N][2],val[N],key[N],size[N],sz; int root,x,y,z,op; inline void update(int x){size[x]=size[son[x][1]]+size[son[x][0]]+1;} inline int New(int V){ size[++sz]=1; val[sz]=V; key[sz]=rand(); son[sz][1]=son[sz][0]=0; return sz; } inline int merge(int A,int B){ if(!A||!B)return A^B; if(key[A]<key[B]){ son[A][1]=merge(son[A][1],B); update(A); return A; } else{ son[B][0]=merge(A,son[B][0]); update(B);return B; } } inline void split(int now,int k,int &x,int &y){ if(!now)x=y=0; else{ if(val[now]<=k) x=now,split(son[now][1],k,son[now][1],y); else y=now,split(son[now][0],k,x,son[now][0]); update(now); } } inline int Kth(int now,int k){ if(size[son[now][0]]>=k)return Kth(son[now][0],k); if(size[son[now][0]]+1==k)return now; return Kth(son[now][1],k-1-size[son[now][0]]); } inline void insert(int V){ split(root,V,x,y); root=merge(x,New(V)); root=merge(root,y); } inline void Del(int V){ split(root,V,x,z); split(x,V-1,x,y); y=merge(son[y][0],son[y][1]); root=merge(x,y); root=merge(root,z); } inline void Rank(int V){ split(root,V-1,x,y); printf("%d\n",size[x]+1); root=merge(x,y); } inline void Find(int V){ printf("%d\n",val[Kth(root,V)]); } inline void Pre(int V){ split(root,V-1,x,y); printf("%d\n",val[Kth(x,size[x])]); root=merge(x,y); } inline void Nxt(int V){ split(root,V,x,y); printf("%d\n",val[Kth(y,1)]); root=merge(x,y); } int n,a; int main() { srand(20190627); scanf("%d",&n); while(n--){ scanf("%d%d",&op,&a); switch(op){ case 1:insert(a);break; case 2:Del(a);break; case 3:Rank(a);break; case 4:Find(a);break; case 5:Pre(a);break; case 6:Nxt(a);break; } } }
原文:https://www.cnblogs.com/chiyo/p/11098954.html