P3369 【模板】普通平衡树 treap树旋转版
#include<bits/stdc++.h> #define INF INT_MAX using namespace std; const int maxn=100010; int sum=0,R=0; int sz[maxn],v[maxn],num[maxn],rd[maxn],son[maxn][2]; //更新p子树的大小 void pushup(int p){ sz[p]=sz[son[p][0]]+sz[son[p][1]]+num[p]; } //旋转 void rot(int&p,int d){ int k=son[p][d^1]; son[p][d^1]=son[k][d]; son[k][d]=p; pushup(p); pushup(k); p=k; } //插入 void ins(int &p,int x){ if (!p){ p=++sum; sz[p]=num[p]=1; v[p]=x; rd[p]=rand(); return ; } if(v[p]==x){ num[p]++; sz[p]++; return ; } int d=(x>v[p]);//右子树 ins(son[p][d],x); if (rd[p]<rd[son[p][d]]) rot(p,d^1); pushup(p); } //删除 void del(int &p,int x){ if(!p) return ; if(x<v[p]) del(son[p][0],x); else if(x>v[p]) del(son[p][1],x); else { if(!son[p][0]&&!son[p][1]){ num[p]--;sz[p]--; if (!num[p]) p=0; } else if(!son[p][1]){ rot(p,1); del(son[p][1],x); } else if(!son[p][0]){ rot(p,0); del(son[p][0],x); } else{ int d=(rd[son[p][0]]>rd[son[p][1]]); rot(p,d); del(son[p][d],x); } } pushup(p); } //x的排名 int get_rank(int p,int x){ if(!p) return 0; if(v[p]==x) return sz[son[p][0]]+1; if(v[p]<x) return sz[son[p][0]]+num[p]+get_rank(son[p][1],x); if(v[p]>x) return get_rank(son[p][0],x); } //排名x的值 int func_find(int p,int x){ if(!p) return 0; if(sz[son[p][0]]>=x) return func_find(son[p][0],x); else if(sz[son[p][0]]+num[p]<x) return func_find(son[p][1],x-num[p]-sz[son[p][0]]); else return v[p]; } //前驱 int pre(int p,int x){ if (!p) return -INF; if (v[p]>=x) return pre(son[p][0],x); else return max(v[p],pre(son[p][1],x)); } //后继 int suc(int p,int x){ if (!p) return INF; if(v[p]<=x) return suc(son[p][1],x); else return min(v[p],suc(son[p][0],x)); } int main() { int n,op,x; cin>>n; while(n--) { cin>>op>>x; if (op==1) ins(R,x); else if(op==2) del(R,x); else if(op==3) cout<<get_rank(R,x)<<endl; else if(op==4) cout<<func_find(R,x)<<endl; else if(op==5) cout<<pre(R,x)<<endl; else if(op==6) cout<<suc(R,x)<<endl; } }