[BZOJ 3224] [Tyvj 1728] 普通平衡树
2015-06-16 20:32
411 查看
3224: Tyvj 1728 普通平衡树
Time Limit: 10 SecMemory Limit: 128 MBDescription
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: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
101 106465
4 1
1 317721
1 460929
1 644985
1 84185
1 89851
6 81968
1 492737
5 493598
Sample Output
10646584185
492737
HINT
1.n的数据范围:n<=1000002.每个数的数据范围:[-1e7,1e7]
【题解】
平衡树模板题目。
#include<bits/stdc++.h> using namespace std; const int N=100010; int fa ,ch [2],root,k ,ind=0,size ; void zig(int x) { int y=fa[x],z=fa[y]; fa[y]=x; fa[x]=z; ch[y][0]=ch[x][1],fa[ch[x][1]]=y,ch[x][1]=y; if (y==ch[z][0]) ch[z][0]=x; else ch[z][1]=x; size[y]=size[ch[y][0]]+size[ch[y][1]]+1; } void zag(int x) { int y=fa[x],z=fa[y]; fa[y]=x,fa[x]=z; ch[y][1]=ch[x][0],fa[ch[x][0]]=y,ch[x][0]=y; if (y==ch[z][0]) ch[z][0]=x; else ch[z][1]=x; size[y]=size[ch[y][0]]+size[ch[y][1]]+1; } void splay(int x,int s) { while (fa[x]!=s) { int y=fa[x],z=fa[y]; if (z==s) { if (x==ch[y][0]) zig(x); else zag(x); break; } if (y==ch[z][0]) { if (x==ch[y][0]) zig(y),zig(x); else zag(x),zig(x); } else { if (x==ch[y][1]) zag(y),zag(x); else zig(x),zag(x); } } size[x]=size[ch[x][0]]+size[ch[x][1]]+1; if (s==0) root=x; } inline void newnode(int &x,int fax,int key) { x=++ind; ch[x][0]=ch[x][1]=0; fa[x]=fax; k[x]=key; } inline int search(int w) { int p,x=root; while(x) { p=x; if(k[x]>w) x=ch[x][0]; else x=ch[x][1]; } return p; } inline void ins(int w){ if (root==0) { newnode(root,0,w); return ; } int i=search(w); if(w<k[i]) newnode(ch[i][0],i,w); else newnode(ch[i][1],i,w); splay(ind,0); } int getsm(int w) { int x=root,ans=ind+1; while(x) { if (k[x]>w) {x=ch[x][0];continue;} if (k[x]<w) {x=ch[x][1];continue;} if (k[x]==w) { ans=x; x=ch[x][0]; } } if (ans==ind+1) return -1; return ans; } inline int getmax(int x) {while(ch[x][1]) x=ch[x][1]; return x;} inline int getmin(int x) {while(ch[x][0]) x=ch[x][0]; return x;} inline int getpre(int x) {return getmax(ch[root][0]);} inline int getnext(int x) {return getmin(ch[root][1]);} inline void del(int w) { int x=getsm(w); splay(x,0); int pp=getpre(x),nn=getnext(x); splay(pp,0);splay(nn,root); int y=fa[x]; fa[x]=0; if(x==ch[y][0]) ch[y][0]=0; else ch[x][0]=0; size[y]=size[ch[y][0]]+size[ch[y][1]]+1; size[root]=size[ch[root][0]]+size[ch[root][1]]+1; } inline int ffind(int w) { int x=getsm(w); splay(x,0); return size[ch[x][0]]; } int findkth(int x,int kth) { int s=size[ch[x][0]]; if(kth==s+1) return k[x]; if(s>=kth) return findkth(ch[x][0],kth); else return findkth(ch[x][1],kth-s-1); } int getp(int w) { int y=getsm(w); ins(w); if(y!=-1) splay(y,0); int ans=getmax(ch[root][0]); del(w); return k[ans]; } int getn(int w) { ins(w); int ans=getmin(ch[root][1]); del(w); return k[ans]; } int main() { int q; root=0; ins(-5000000);ins(5000000); scanf("%d",&q); while (q--) { int x,k; scanf("%d%d",&x,&k); if (x==1) ins(k); else if (x==2) del(k); else if (x==3) printf("%d\n",ffind(k)); else if (x==4) printf("%d\n",findkth(root,k+1)); else if (x==5) printf("%d\n",getp(k)); else if (x==6) printf("%d\n",getn(k)); } return 0; }
View Code
还是习惯分开来写Zig-Zag
相关文章推荐
- Android-ProgressBar
- 最长公共前缀
- MVC在安卓应用,ANR,Force Close,Contentprovider实现数据共享
- log4j输出格式
- cocoa 的大招(KVC的几点强大应用记录)
- java流程图
- centos 安装gdb
- 47Exchange 2010升级到Exchange 2013-迁移地址列表&OAB
- JAVA学习笔记二
- Apache与Nginx优缺点比较
- poj 1270 Following Orders 枚举排列
- poj 1363 Rails 【栈】
- Count Complete Tree Nodes
- 抽象类与接口的区别
- Android DOM解析XML方法及优化
- OpenGL Tutorial: (1) Setting up OpenGL with Visual Studio
- java获取各种路径的方法
- UVa 572 - Oil Deposits【图DFS】
- 动规,当前时间
- 自定义Loader 和 Handler传递参数给UI线程