Description
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数2. 删除x数(若有多个相同的数,因只删除一个)3. 查询x数的排名(若有多个相同的数,因输出最小的排名)4. 查询排名为x的数5. 求x的前驱(前驱定义为小于x,且最大的数)6. 求x的后继(后继定义为大于x,且最小的数)Input
第一行为n,表示操作的个数,下面n行每行有两个数opt和x,opt表示操作的序号(1<=opt<=6)
Output
对于操作3,4,5,6每行输出一个数,表示对应答案
Sample Input
10 1 106465 4 1 1 317721 1 460929 1 644985 1 84185 1 89851 6 81968 1 492737 5 493598
Sample Output
106465 84185 492737
HINT
1.n的数据范围:n<=100000
2.每个数的数据范围:[-1e7,1e7]
数据如下http://pan.baidu.com/s/1jHMJwO2
/* 一个平衡树的模板写了一上午了,能犯的错误基本都犯了。。。 首先没加哨兵,再就是删除操作时没有更新sz(这个巨坑),真是长记性了。 */#include#include #define N 100010using namespace std;int son[N][2],fa[N],val[N],cnt[N],sz[N],m,rt,size;void pushup(int x){ sz[x]=sz[son[x][0]]+sz[son[x][1]]+cnt[x];}void rotate(int x,int &k){ int y=fa[x],z=fa[y],l,r; if(son[y][0]==x) l=0;else l=1;r=l^1; if(y==k) k=x; else { if(son[z][0]==y) son[z][0]=x; else son[z][1]=x; } fa[x]=z;fa[y]=x;fa[son[x][r]]=y; son[y][l]=son[x][r];son[x][r]=y; pushup(y);pushup(x);}void splay(int x,int &k){ while(x!=k){ int y=fa[x],z=fa[y]; if(y!=k){ if((son[y][0]==x)^(son[z][0]==y)) rotate(x,k); else rotate(y,k); } rotate(x,k); }}void insert(int v){ int k=rt,y=0; while(k&&val[k]!=v) y=k,k=son[k][v>val[k]]; if(k) cnt[k]++; else { k=++size;sz[k]=1;cnt[k]=1;fa[k]=y;val[k]=v; if(y) son[y][v>val[y]]=k; } splay(k,rt);}void find1(int v){ //查找v的位置 int k=rt;if(!k)return; while(son[k][v>val[k]]&&val[k]!=v) k=son[k][v>val[k]]; splay(k,rt);}int find2(int x){ //查找排名为x的数 x++; int k=rt; if(sz[k] =x) return k; if(sz[son[k][0]]>=x) k=son[k][0]; else x-=(sz[son[k][0]]+cnt[k]),k=son[k][1]; } return k;}int nxt(int x,int f){ find1(x); if((val[rt]>x&&f)||val[rt] 1){cnt[x]--;sz[x]--;return;} if(!son[x][0]||!son[x][1]){ rt=son[x][0]+son[x][1]; } else { k=son[x][1]; while(son[k][0])k=son[k][0];sz[k]+=sz[son[x][0]]; fa[son[x][0]]=k;son[k][0]=son[x][0]; rt=son[x][1]; } fa[rt]=0;splay(k,rt);}int main(){ insert(-0x7fffffff);insert(0x7fffffff); scanf("%d",&m); for(int i=1;i<=m;i++){ int opt,x;scanf("%d%d",&opt,&x); if(opt==1) insert(x); if(opt==2) del(x); if(opt==3) find1(x),printf("%d\n",sz[son[rt][0]]); if(opt==4) printf("%d\n",val[find2(x)]); if(opt==5) printf("%d\n",val[nxt(x,0)]); if(opt==6) printf("%d\n",val[nxt(x,1)]); } return 0;}