题意:
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
题解:
就和题目一样,是一个平衡树(无旋Treap)的模板题,详见代码
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=100000+10; const int Inf=1e9; typedef pair<int,int> D; struct Treap{ int lch,rch; int data,sum,size; #define L(u) a[u].lch #define R(u) a[u].rch }a[maxn]; int n,cnt,root; D Split(int,int); int Merge(int,int); void Pushup(int); void Insert(int); void Delte(int); int GetRank(int,int); int Find(int,int); int GetPre(int,int); int GetNext(int,int); int main(){ // freopen("in.cpp","r",stdin); scanf("%d",&n); int op,x; for(int i=1;i<=n;i++){ scanf("%d%d",&op,&x); if(op==1)Insert(x); else if(op==2)Delte(x); else if(op==3)printf("%d ",GetRank(root,x)); else if(op==4)printf("%d ",Find(root,x)); else if(op==5)printf("%d ",GetPre(root,x)); else printf("%d ",GetNext(root,x)); } return 0; } void Pushup(int u){ a[u].size=a[L(u)].size+a[R(u)].size+1; } D Split(int u,int k){ if(u==0)return D(0,0); D y; int num=a[L(u)].size; if(num>=k){ y=Split(a[u].lch,k); a[u].lch=y.second; Pushup(u); y.second=u; }else{ y=Split(a[u].rch,k-num-1); a[u].rch=y.first; Pushup(u); y.first=u; } return y; } int Merge(int A,int B){ if(A==0)return B; if(B==0)return A; if(rand()%(a[A].size+a[B].size)<a[A].size){ a[A].rch=Merge(a[A].rch,B); Pushup(A); return A; }else{ a[B].lch=Merge(A,a[B].lch); Pushup(B); return B; } } int GetRank(int u,int x){ int ans=0,tmp=Inf; while(u){ if(x==a[u].data)tmp=min(tmp,ans+a[L(u)].size+1); if(x>a[u].data)ans+=a[L(u)].size+1,u=a[u].rch; else u=a[u].lch; } if(tmp==Inf)return ans; return tmp; } int Find(int u,int x){ while(1){ if(a[L(u)].size==x-1)return a[u].data; if(a[L(u)].size>x-1)u=a[u].lch; else x=x-a[L(u)].size-1,u=a[u].rch; } } int GetPre(int u,int x){ int ans=-Inf; while(u){ if(a[u].data<x)ans=max(ans,a[u].data),u=a[u].rch; else u=a[u].lch; } return ans; } int GetNext(int u,int x){ int ans=Inf; while(u){ if(a[u].data>x)ans=min(ans,a[u].data),u=a[u].lch; else u=a[u].rch; } return ans; } void Insert(int x){ int k=GetRank(root,x); D tmp=Split(root,k); a[++cnt].data=x; a[cnt].size=1; root=Merge(tmp.first,cnt); root=Merge(root,tmp.second); } void Delte(int x){ int k=GetRank(root,x); D t1=Split(root,k); D t2=Split(t1.first,k-1); root=Merge(t2.first,t1.second); }