bzoj3224 普通平衡树 splay模板题
来源:互联网 发布:报表数据的重要性 编辑:程序博客网 时间:2024/05/20 04:13
题目链接:戳这里
3224: Tyvj 1728 普通平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 17768 Solved: 7799
[Submit][Status][Discuss]
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
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
84185
492737
HINT
1.n的数据范围:n<=100000
2.每个数的数据范围:[-2e9,2e9]
代码:
#include<bits/stdc++.h>#define maxn 100005using namespace std;typedef long long LL;int read(){char c;int sum=0,f=1;c=getchar();while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0' && c<='9'){sum=sum*10+c-'0';c=getchar();}return sum*f;}int n,opt,x;int fa[maxn],son[maxn][2],val[maxn],cnt[maxn],size[maxn],sz,root;void clear(int x){son[x][1]=son[x][0]=fa[x]=val[x]=cnt[x]=size[x]=0;}bool getson(int x){return son[fa[x]][1]==x;}void pushup(int x){if(x){size[x]=cnt[x];if(son[x][0]) size[x]+=size[son[x][0]];if(son[x][1]) size[x]+=size[son[x][1]];}}void rotate(int x){int y=fa[x],z=fa[y],s=getson(x);son[y][s]=son[x][s^1];fa[son[y][s]]=y;fa[y]=x;son[x][s^1]=y;fa[x]=z;if(z)son[z][son[z][1]==y]=x;pushup(y);pushup(x);}void splay(int x,int k){for(int y;(y=fa[x])!=k;rotate(x))if(fa[y]!=k)rotate((getson(x)==getson(y))?y:x);if(!k) root=x;}void insert(int x){if(root==0){sz++;root=sz;son[sz][0]=son[sz][1]=fa[sz]=0;val[sz]=x;size[sz]=cnt[sz]=1;return;}int now=root,f=0;while(1){if(val[now]==x){cnt[now]++;pushup(now);pushup(f);splay(now,0);break;}f=now;now=son[now][val[now]<x];if(now==0){sz++;son[sz][0]=son[sz][1]=0;fa[sz]=f;val[sz]=x;size[sz]=cnt[sz]=1;son[f][val[f]<x]=sz;pushup(f);splay(sz,0);break;}}}int find(int x){int ans=0,now=root;while(1){if(x<val[now])now=son[now][0];else{ans+=(son[now][0]?size[son[now][0]]:0);if(x==val[now]){splay(now,0);return ans+1; }ans+=cnt[now];now=son[now][1];}}}int findx(int x){int now=root;while(1){if(son[now][0] && x<=size[son[now][0]])now=son[now][0];else{int temp=(son[now][0]?size[son[now][0]]:0)+cnt[now];if(x<=temp)return val[now];x-=temp;now=son[now][1];}}}int pre(){int now=son[root][0];while(son[now][1])now=son[now][1]; return now;}int nex(){int now=son[root][1];while(son[now][0])now=son[now][0];return now;}void del(int x){find(x);if(cnt[root]>1){cnt[root]--;return;}if(!son[root][0] && !son[root][1]){clear(root);root=0;return;}int oldroot=root;if(!son[root][0]){root=son[root][1];fa[root]=0;clear(oldroot);return;}else if(!son[root][1]){root=son[root][0];fa[root]=0;clear(oldroot);return;}splay(pre(),0);fa[son[oldroot][1]]=root;son[root][1]=son[oldroot][1];clear(oldroot);pushup(root);}int main(){n=read();for(int i=1;i<=n;i++){opt=read();x=read();switch (opt){case 1:insert(x);break;case 2:del(x);break;case 3:printf("%d\n",find(x));break;case 4:printf("%d\n",findx(x));break; case 5:insert(x);printf("%d\n",val[pre()]);del(x);break; case 6:insert(x);printf("%d\n",val[nex()]);del(x);break; }}return 0;}
阅读全文