平衡树
2016-04-15 08:17
423 查看
#include<iostream> #include<cstdio> #include<map> using namespace std; map<int,int> bh; int key[100010]; int fa[100010]; int ch[100010][2]; int sz[100010]; int cnt[100010]; int t1,t2,tot,root; int inf=2147483646; bool dir(int x){return x==ch[fa[x]][1];} void find_pre(int i,int x){ if(key[i]==0) return ; if(key[i]<x){ t1=key[i]; find_pre(ch[i][1],x); } else find_pre(ch[i][0],x); } void find_nxt(int i,int x){ if(key[i]==0) return ; if(key[i]>x){ t2=key[i]; find_nxt(ch[i][0],x); } else find_nxt(ch[i][1],x); } void up(int x){ sz[0]=0; sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+cnt[x]; } void rotate(int x){ bool b=dir(x);int y=fa[x]; int z=fa[y];int a=ch[x][!b]; if(z==0) root=x; else ch[z][dir(y)]=x; fa[x]=z;fa[y]=x; ch[x][!b]=y;ch[y][b]=a; if(a!=0) fa[a]=y; up(y);up(x); if(z!=0)up(z); } void splay(int x,int i){ bool b,c; while(fa[x]!=i){ int y=fa[x];int z=fa[y]; if(z==i) rotate(x); else{ b=dir(x),c=dir(y); if(b^c) { rotate(x);rotate(x);} else { rotate(y);rotate(x);} } } if(i==0) root=x; } void insert(int k,int x,int last){ if(x==key[k]){ cnt[k]++; up(k); up(fa[k]); return ; } if(!k){ k=++tot; bh[x]=k; key[k]=x; cnt[k]=1; sz[k]=1; fa[k]=last; if(key[k]<key[last]) ch[last][0]=k; else ch[last][1]=k; splay(k,0); return ; } if(x<key[k]){ insert(ch[k][0],x,k); up(k); return ; } else{ insert(ch[k][1],x,k); up(k); return ; } } void del(int y){ int x=bh[y]; splay(x,0); cnt[x]--;sz[x]--; if(cnt[x]==0){ sz[0]=0; if(sz[ch[x][0]]==0){ root=ch[x][1]; fa[ch[x][1]]=0; } else if(sz[ch[x][1]]==0){ root=ch[x][0]; fa[ch[x][0]]=0; } else{ t1=-inf; find_pre(root,y); int h=bh[t1]; splay(h,x); root=h; fa[h]=0; ch[h][1]=ch[x][1]; fa[ch[x][1]]=h; up(root); } key[x]=0; fa[x]=0; ch[x][0]=0; ch[x][1]=0; } } int rank_to_num(int dq,int rank){ sz[0]=0; if(sz[ch[dq][0]]>=rank) return rank_to_num(ch[dq][0],rank); if(sz[ch[dq][0]]+cnt[dq]<rank) return rank_to_num(ch[dq][1],rank-sz[ch[dq][0]]-cnt[dq]); return key[dq]; } int main() { int n,x,y;scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d",&x,&y); if(x==1){ insert(root,y,0); up(root); } if(x==2) del(y); if(x==3){ sz[0]=0; splay(bh[y],0); printf("%d\n",sz[ch[root][0]]+1); } if(x==4) printf("%d\n",rank_to_num(root,y)); if(x==5){ t1=y; find_pre(root,y); printf("%d\n",t1); } if(x==6){ t2=inf; find_nxt(root,y); printf("%d\n",t2); } } return 0; }
相关文章推荐
- bzoj 4524: [Cqoi2016]伪光滑数 优先队列
- 【Android】实验6 在应用程序中播放音频和视频 截止提交报告时间2016.4.21
- node.js npm 提示 Error: ENOENT stat 报错的解决方法
- 计算fibnacci 级数的几种方法
- Python编程习惯
- python编程之import篇
- 如何在一个创业公司做好架构师
- Oracle-27-集合操作(交集、并集、差集)&子查询之单行子查询
- POJ 【3278】 Catch That Cow
- Android 基本控件的使用四(仿团购底部菜单App)(RadioGroup)
- mysql _error insert
- Hive中文注释乱码问题的解决
- UVa1585 习题3-1
- 通过修改注册表解决——任务管理器禁用问题
- python调用caffe模型进行classify时读入mean文件错误:mean shape incompatible with input shape
- STL迭代器失效问题
- 转: Apache SSI详解及应用
- jquery中prop()方法和attr()方法的区别浅析
- 【福昕PDF阅读器】当前文件兼容于PDFA且以不接受修改的只读模式打开
- strut获取作用对象的两种方式