【bzoj3224】Tyvj 1728 普通平衡树
2017-04-14 21:03
411 查看
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
代码(splay)
代码(treap)
您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作:
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
代码(splay)
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> int c[1000005][2],fa[1000005],size[1000005],num[2000005]; int cnt,n,rt,ans; inline int read() { int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1; ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f; } inline void update(int x) { int l=c[x][0],r=c[x][1]; size[x]=size[l]+size[r]+1; } using namespace std; void rotate(int x,int &k) { int l,r,y=fa[x],z=fa[y]; if (c[y][0]==x) l=0;else l=1;r=l^1; if (y==k) k=x; else if (c[z][0]==y) c[z][0]=x;else c[z][1]=x; fa[x]=z;fa[y]=x; fa[c[x][r]]=y;c[y][l]=c[x][r]; c[x][r]=y; update(y);update(x); } void splay(int x,int &k) { int y,z; while (x!=k) { y=fa[x];z=fa[y]; if (y!=k) { if (c[z][0]==y^c[y][0]==x) rotate(x,k);else rotate(y,k); } rotate(x,k); } } void insert(int &k,int x,int f) { if (k==0){k=++cnt;num[k]=x;fa[k]=f;size[k]=1;splay(k,rt);return;} if (x>=num[k]) insert(c[k][1],x,k);else insert(c[k][0],x,k); } void find(int k,int x) { if (k==0) return; if (num[k]==x){ans=k;find(c[k][0],x);return;} if (num[k]>x) find(c[k][0],x);else find(c[k][1],x); } void query_before(int k,int x) { if (k==0) return; if (num[k]<x) {ans=k;query_before(c[k][1],x);} else query_before(c[k][0],x); } void query_after(int k,int x) { if (k==0) return; if (num[k]>x) {ans=k;query_after(c[k][0],x);} else query_after(c[k][1],x); } void cl(int &x) { if (c[x][0]) cl(c[x][0]); else if (c[x][1]) cl(c[x][1]); else ans=fa[x],x=0; } void del(int x) { ans=0; query_before(rt,x); int x1=ans; ans=0; query_after(rt,x); int x2=ans; splay(x1,rt);splay(x2,c[rt][1]); cl(x2); splay(ans,rt); } int query_rank(int x) { ans=0; find(rt,x); x=ans; if (x!=0) splay(x,rt); return size[c[x][0]]; } int query_num(int k,int x) { int l=c[k][0],r=c[k][1]; if (size[l]+1==x) return k; if (size[l]>=x) return query_num(l,x);else return query_num(r,x-size[l]-1); } int main() { n=read(); int opt,x; insert(rt,-2000000001,0); insert(rt,2000000001,0); while (n--) { opt=read();x=read(); if (opt==1) insert(rt,x,0); if (opt==2) del(x); if (opt==3) printf("%d\n",query_rank(x)); if (opt==4) printf("%d\n",num[query_num(rt,x+1)]); if (opt==5) { query_before(rt,x); printf("%d\n",num[ans]); } if (opt==6) { query_after(rt,x); printf("%d\n",num[ans]); } } return 0; }
代码(treap)
#include<cstdio> #include<iostream> #include<cstring> #include<cmath> #include<algorithm> #define N 1000005 int n,cnt,rt,ans; int size ,sum ,rnd ,num ,ls ,rs ; inline int read() { int x=0,f=1;char ch=getchar(); while (ch<'0'||ch>'9'){if (ch=='-') f=-1; ch=getchar();} while (ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();} return x*f; } inline void update(int k) { size[k]=size[ls[k]]+size[rs[k]]+sum[k]; } inline void lturn(int &k) { int t=rs[k];rs[k]=ls[t];ls[t]=k; size[t]=size[k];update(k);k=t; } inline void rturn(int &k) { int t=ls[k];ls[k]=rs[t];rs[t]=k; size[t]=size[k];update(k);k=t; } using namespace std; void insert(int &k,int x) { if (k==0){k=++cnt;size[k]=1;num[k]=x;sum[k]=1;rnd[k]=rand();return;} size[k]++; if (num[k]==x)sum[k]++; else if (x>num[k]) { insert(rs[k],x); if (rnd[rs[k]]<rnd[k])lturn(k); } else { insert(ls[k],x); if (rnd[ls[k]]<rnd[k])rturn(k); } } void del(int &k,int x) { if (k==0) return; if (num[k]==x) { if (sum[k]>1) { sum[k]--;size[k]--;return; } if (rs[k]*ls[k]==0) k=rs[k]+ls[k]; else if (rnd[ls[k]]<rnd[rs[k]]) rturn(k),del(k,x); else lturn(k),del(k,x); } else if (x>num[k]) size[k]--,del(rs[k],x); else size[k]--,del(ls[k],x); } int query_rank(int k,int x) { if (k==0) return 0; if (num[k]==x) return size[ls[k]]+1; else if (x>num[k]) return size[ls[k]]+sum[k]+query_rank(rs[k],x); else return query_rank(ls[k],x); } int query_num(int k,int x) { if (k==0) return 0; if (x<=size[ls[k]]) return query_num(ls[k],x); else if (x>size[ls[k]]+sum[k]) return query_num(rs[k],x-size[ls[k]]-sum[k]); else return num[k]; } void query_pro(int k,int x) { if (k==0) return; if (num[k]<x)ans=k,query_pro(rs[k],x); else query_pro(ls[k],x); } void query_sub(int k,int x) { if (k==0) return; if (num[k]>x)ans=k,query_sub(ls[k],x); else query_sub(rs[k],x); } int main() { n=read(); int opt,x; while (n--) { opt=read();x=read(); switch(opt) { case 1:insert(rt,x);break; case 2:del(rt,x);break; case 3:printf("%d\n",query_rank(rt,x));break; case 4:printf("%d\n",query_num(rt,x));break; case 5:ans=0;query_pro(rt,x);printf("%d\n",num[ans]);break; case 6:ans=0;query_sub(rt,x);printf("%d\n",num[ans]);break; } } return 0; }
相关文章推荐
- [BZOJ]3224: Tyvj 1728 普通平衡树
- [Bzoj3224]Tyvj 1728 普通平衡树
- bzoj 3224: Tyvj 1728 普通平衡树
- 【Treap】[BZOJ 3224]Tyvj 1728 普通平衡树
- bzoj 3224,tyvj 1728普通平衡树
- bzoj 3224: Tyvj 1728 普通平衡树
- [bzoj 3224] Tyvj 1728 普通平衡树(Splay)
- BZOJ 3224 Tyvj 1728 普通平衡树
- bzoj3224: Tyvj 1728 普通平衡树(平衡树)
- [替罪羊树 模板题] BZOJ 3224 Tyvj 1728 普通平衡树
- bzoj 3224 Tyvj 1728 普通平衡树 [Splay]
- BZOJ3224: Tyvj 1728 普通平衡树
- BZOJ 3224: Tyvj 1728 普通平衡树
- BZOJ3224[Tyvj 1728 普通平衡树]题解--Treap
- [bzoj3224][tyvj1728][普通平衡树] (pb_ds库自带红黑树)
- BZOJ 3224: Tyvj 1728 普通平衡树 treap
- bzoj3224 Tyvj 1728 普通平衡树
- bzoj3224: Tyvj 1728 普通平衡树(打个splay暖暖手)
- BZOJ 3224: Tyvj 1728 普通平衡树 treap
- 【treap】【bzoj 3224】: Tyvj 1728 普通平衡树