bzoj 3224: Tyvj 1728 普通平衡树 (Splay模板)
2016-09-26 23:02
507 查看
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=3224
题意:
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
分析:
平衡树的入门题,可以当做一般平衡树操作的模板了~~
这题我是WA了好多次,我是用http://blog.csdn.net/crazy_ac/article/details/8034190这个大神的模板,不过总是WA,改了一些地方终于AC了,前几天可是耗费了我一天的功夫啊!,还是太菜了QAQ
代码:
题意:
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
1. 插入x数
2. 删除x数(若有多个相同的数,因只删除一个)
3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
4. 查询排名为x的数
5. 求x的前驱(前驱定义为小于x,且最大的数)
6. 求x的后继(后继定义为大于x,且最小的数)
分析:
平衡树的入门题,可以当做一般平衡树操作的模板了~~
这题我是WA了好多次,我是用http://blog.csdn.net/crazy_ac/article/details/8034190这个大神的模板,不过总是WA,改了一些地方终于AC了,前几天可是耗费了我一天的功夫啊!,还是太菜了QAQ
代码:
#include<cstdio> #include<cstdlib> const int inf = ~0u>>2; #define L ch[x][0] #define R ch[x][1] #define KT (ch[ ch[rt][1] ][0]) const int maxn = 1e5+9; int lim; struct SplayTree { int sz[maxn]; int ch[maxn][2]; int pre[maxn]; int rt,top; inline void up(int x) { sz[x] = cnt[x] + sz[ L ] + sz[ R ]; } inline void Rotate(int x,int f) { int y=pre[x]; ch[y][!f] = ch[x][f]; pre[ ch[x][f] ] = y; pre[x] = pre[y]; if(pre[x]) ch[ pre[y] ][ ch[pre[y]][1] == y ] =x; ch[x][f] = y; pre[y] = x; up(y); } inline void Splay(int x,int goal) { //将x旋转到goal的下面 while(pre[x] != goal) { if(pre[pre[x]] == goal) Rotate(x , ch[pre[x]][0] == x); else { int y=pre[x],z=pre[y]; int f = (ch[z][0]==y); if(ch[y][f] == x) Rotate(x,!f),Rotate(x,f); else Rotate(y,f),Rotate(x,f); } } up(x); if(goal==0) rt=x; } inline void RTO(int k,int goal) { //将第k位数旋转到goal的下面 int x=rt; while(sz[ L ] != k-1) { if(k < sz[ L ]+1) x=L; else { k-=(sz[ L ]+1); x = R; } } Splay(x,goal); } inline void Newnode(int &x,int c,int f) { x=++top; L = R = 0; pre[x] = f; sz[x]=1; cnt[x]=1; val[x] = c; } inline void init() { ch[0][0]=ch[0][1]=pre[0]=sz[0]=0; rt=top=0; cnt[0]=0; } inline void Insert(int &x,int key,int f) { if(!x) { Newnode(x,key,f); Splay(x,0);//注意插入完成后splay return ; } if(key==val[x]) { cnt[x]++; sz[x]++; Splay(x,0);//注意插入完成后splay return ; } else if(key<val[x]) { Insert(L,key,x); } else { Insert(R,key,x); } up(x); } void Del_root() { //删除根节点 int t=rt; if(ch[rt][1]) { rt=ch[rt][1]; RTO(1,0); ch[rt][0]=ch[t][0]; if(ch[rt][0]) pre[ch[rt][0]]=rt; } else rt=ch[rt][0]; pre[rt]=0; up(rt); } void findpre(int x,int key,int &ans) { //找前驱节点 ans=-inf; while(x) { if(val[x]<key) { if(val[x]>ans)ans=val[x]; x=R; } else x=L; } } void findsucc(int x,int key,int &ans) { //找后继节点 ans=inf; while(x) { if(val[x]>key) { if(val[x]<ans)ans=val[x]; // ans=min(ans,val[x]); x=L; } else x=R; } } inline int find_kth(int x,int k) { //第k小的数 if(k<sz[L]+1) { return find_kth(L,k); } else if(k > sz[ L ] + cnt[x] ) return find_kth(R,k-sz[L]-cnt[x]); else { Splay(x,0); return val[x]; } } int find(int key) { int x=rt; while(x&&val[x]!=key) x=ch[x][key>val[x]]; if(x)Splay(x,0); //0是没找到 return x; } int find(int x,int key) { //if(!x) return 0; while(x&&val[x]!=key)x=ch[x][key>val[x]]; return x; } int rank(int key) { int x = find(key); //Splay(x,rt); return sz[ch[rt][0]]+1; } //确定key的排名 int get_rank(int x) { int *key=val; int r=rt,temp=0; while(ch[r][key[r]<=x]) { if(key[r]==x) break; if(key[r]<=x) temp+=sz[r]-sz[ch[r][1]]; r=ch[r][key[r]<=x]; } return sz[ch[r][0]]+1+temp; } int getrank(int x,int key,int cur) { //cur:当前已知比要求元素(key)小的数的个数 if(key == val[x]) return sz[L] + cur + 1; else if(key < val[x]) return getrank(L,key,cur); else return getrank(R,key,cur+sz[L]+cnt[rt]); } void del(int &x,int f) { //删除小于lim的所有的数所在的节点 if(!x) return ; if(val[x]>=lim) { del(L,x); } else { x=R; pre[x]=f; if(f==0) rt=x; del(x,f); } if(x) up(x); } void Delete(int key) { int node=find(rt,key); Splay(node,0); cnt[rt]--; if(cnt[rt]<=0)Del_root(); } void solve(int n) { int x,op,ans,tot=0; for(int i=0; i<n; i++) { scanf("%d%d",&op,&x); if(op==1) { Insert(rt,x,0); continue; } else if(op==2) { Delete(x); continue; } else if(op==3) { ans=rank(x); } else if(op==4) { ans=find_kth(rt,x); } else if(op==5) { findpre(rt,x,ans); } else if(op==6) { findsucc(rt,x,ans); } printf("%d\n",ans); } } int cnt[maxn]; int val[maxn]; int lim; } spt; int main() { int n; while(~scanf("%d",&n)) { spt.init(); spt.solve(n); } return 0; }
相关文章推荐
- bzoj 3224: Tyvj 1728 普通平衡树(splay 模板题)
- [bzoj3224]Tyvj 1728 普通平衡树——splay模板
- 【模板】【bzoj3224】Tyvj 1728 普通平衡树 Splay
- Treap模板 BZOJ 3224: Tyvj 1728 普通平衡树
- bzoj 3224 Tyvj 1728 普通平衡树 (替罪羊树模板)
- BZOJ 3224: Tyvj 1728 普通平衡树 [Splay]【数据结构】
- bzoj3224: Tyvj 1728 普通平衡树(打个splay暖暖手)
- 【模板】【bzoj3224】Tyvj 1728 普通平衡树 Treap
- 【bzoj3224】【Tyvj1728】【普通平衡树】【splay】
- BZOJ 3224 Tyvj 1728 普通平衡树 (Splay)
- BZOJ 3224 Tyvj 1728 普通平衡树 | Splay 板子+SPlay详细讲解
- bzoj 3224==tyvj 1728普通平衡树 splay
- _bzoj3224 Tyvj 1728 普通平衡树【Splay】
- BZOJ 3224 TYVJ 1728 普通平衡树 [Treap树模板]
- bzoj 3224 Tyvj 1728 普通平衡树 [Splay]
- [bzoj 3224] Tyvj 1728 普通平衡树(Splay)
- 【Splay】bzoj3224 Tyvj 1728 普通平衡树
- 【BZOJ】3224 Tyvj 1728 普通平衡树 平衡树模板
- [替罪羊树 模板题] BZOJ 3224 Tyvj 1728 普通平衡树
- 【BZOJ】3224 Tyvj 1728 普通平衡树 平衡树模板