学习了下treap
#include<iostream> #include<cstdio> #include<cstdlib> using namespace std; const int inf=1<<29; int n,mn,root,delta,tot,ans; int size[100010],child[100010][2],cnt[100010],key[100010],p[100010]; void update(int x) { size[x]=size[child[x][0]]+size[child[x][1]]+cnt[x]; } void rotate(int&x,int t) { int y=child[x][t]; child[x][t]=child[y][1-t]; child[y][1-t]=x; update(x); update(y); x=y; } void insert(int&x,int k) { if(x) { if(key[x]==k) cnt[x]++; else { int t=key[x]<k; insert(child[x][t],k); if(p[x]<p[child[x][t]]) rotate(x,t); } } else { ++tot; x=tot; p[x]=rand(); // printf("%d\n",p[x]); key[x]=k; cnt[x]=1; } update(x); } void erase(int&x,int k) { if(key[x]==k) { if(cnt[x]>1) { cnt[x]--; update(x); return; } if(!child[x][0]&&!child[x][1]) { x=0; return; } int t=p[child[x][1]]>p[child[x][0]]; rotate(x,t); erase(child[x][t^1],k); } else erase(child[x][key[x]<k],k); update(x); } int find(int x,int k) { if(k<=size[child[x][0]]) return find(child[x][0],k); k-=size[child[x][0]]+cnt[x]; if(k<=0) return key[x]; return find(child[x][1],k); } int findrank(int x,int k) { if(key[x]==k) return size[child[x][0]]+1; if(key[x]<k) return findrank(child[x][1],k)+cnt[x]+size[child[x][0]]; if(key[x]>k) return findrank(child[x][0],k); } void findpro(int x,int k) { if(x==0) return; if(key[x]<k) { ans=key[x]; findpro(child[x][1],k); } else findpro(child[x][0],k); } void findnxt(int x,int k) { if(x==0) return; if(key[x]>k) { ans=key[x]; findnxt(child[x][0],k); } else findnxt(child[x][1],k); } int main() { p[0]=-inf; scanf("%d",&n); while(n--) { int opt,a; scanf("%d%d",&opt,&a); // printf("----------\nopt=%d\n",opt); if(opt==1) insert(root,a); if(opt==2) erase(root,a); if(opt==3) printf("%d\n",findrank(root,a)); if(opt==4) printf("%d\n",find(root,a)); if(opt==5) {findpro(root,a);printf("%d\n",ans);ans=0;} if(opt==6) {findnxt(root,a);printf("%d\n",ans);ans=0;} // printf("----------\n"); } return 0; }