您的位置:首页 > 其它

BZOJ 3224: Tyvj 1728 普通平衡树

2016-12-10 10:44 381 查看

3224: Tyvj 1728 普通平衡树

Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 9286 Solved: 3935
[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

Sample Output

106465

84185

492737

HINT

1.n的数据范围:n<=100000

2.每个数的数据范围:[-1e7,1e7]

数据如下http://pan.baidu.com/s/1jHMJwO2

Source

平衡树

分析:

还是模板题...讲道理这道题我写了3遍才AC...QAQ...

代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
//by NeighThorn
#define inf 1e7+7
using namespace std;

const int maxn=100000+5;

int n,opt;
int root,tot,w[maxn],ls[maxn],rs[maxn],fa[maxn],cnt[maxn],siz[maxn];

inline void zig(int x){
int y=fa[x],tmp=siz[y];
if(rs[x])
ls[y]=rs[x],fa[rs[x]]=y,siz[y]=siz[y]-siz[x]+siz[rs[x]],siz[x]=tmp;
else
ls[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp;
fa[x]=fa[y];
if(fa[x]){
if(ls[fa[x]]==y)
ls[fa[x]]=x;
else
rs[fa[x]]=x;
}
fa[y]=x,rs[x]=y;
}

inline void zag(int x){
int y=fa[x],tmp=siz[y];
if(ls[x])
rs[y]=ls[x],fa[ls[x]]=y,siz[y]=siz[y]-siz[x]+siz[ls[x]],siz[x]=tmp;
else
rs[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp;
fa[x]=fa[y];
if(fa[x]){
if(ls[fa[x]]==y)
ls[fa[x]]=x;
else
rs[fa[x]]=x;
}
fa[y]=x,ls[x]=y;
}

inline void splay(int x,int z){
while(fa[x]!=z){
int y=fa[x];
if(fa[y]==z){
if(ls[y]==x)
zig(x);
else
zag(x);
}
else{
if(ls[fa[y]]==y){
if(ls[y]==x)
zig(y),zig(x);
else
zag(x),zig(x);
}
else{
if(rs[y]==x)
zag(y),zag(x);
else
zig(x),zag(x);
}
}
}
if(!z)
root=x;
}

inline void ins(int rt,int x){
if(!rt)
w[++tot]=x,siz[tot]=1,cnt[tot]=1,root=tot;
else if(w[rt]==x)
cnt[rt]++,siz[rt]++,splay(rt,0);
else if(x<w[rt]){
if(!ls[rt])
w[++tot]=x,cnt[tot]=siz[tot]=1,siz[rt]++,fa[tot]=rt,ls[rt]=tot,splay(tot,0);
else
siz[rt]++,ins(ls[rt],x);
}
else{
if(!rs[rt])
w[++tot]=x,cnt[tot]=siz[tot]=1,siz[rt]++,fa[tot]=rt,rs[rt]=tot,splay(tot,0);
else
siz[rt]++,ins(rs[rt],x);
}
}

inline void del(int rt,int x){
if(w[rt]==x){
splay(rt,0);
if(cnt[rt]>1)
cnt[rt]--,siz[rt]--;
else{
int l=ls[rt],r=rs[rt];
if(!l)
ls[rt]=rs[rt]=fa[rt]=siz[rt]=cnt[rt]=0,fa[r]=0,root=r;
else{
while(rs[l])
l=rs[l];
splay(l,rt);ls[rt]=rs[rt]=fa[rt]=siz[rt]=cnt[rt]=0;fa[r]=l,rs[l]=r,siz[l]+=siz[r];root=l,fa[l]=0;
}
}
}
else if(x<w[rt])
del(ls[rt],x);
else
del(rs[rt],x);
}

inline int pre(int rt,int x){
int res=-inf;
while(rt){
if(w[rt]<x)
res=max(res,w[rt]),rt=rs[rt];
else
rt=ls[rt];
}
return res;
}

inline int suf(int rt,int x){
int res=inf;
while(rt){
if(w[rt]>x)
res=min(res,w[rt]),rt=ls[rt];
else
rt=rs[rt];
}
return res;
}

inline int rank(int rt,int x){
if(w[rt]==x){
splay(rt,0);
if(!ls[rt])
return 1;
else
return siz[ls[rt]]+1;
}
else if(x<w[rt])
return rank(ls[rt],x);
else
return rank(rs[rt],x);
}

inline int query(int rt,int x){
if(!ls[rt]){
if(cnt[rt]>=x){
splay(rt,0);
return w[rt];
}
else
return query(rs[rt],x-cnt[rt]);
}
else{
if(siz[ls[rt]]>=x)
return query(ls[rt],x);
else if(siz[ls[rt]]+cnt[rt]>=x){
splay(rt,0);
return w[rt];
}
else
return query(rs[rt],x-siz[ls[rt]]-cnt[rt]);
}
}

signed main(void){
memset(ls,0,sizeof(ls));
memset(rs,0,sizeof(rs));
memset(fa,0,sizeof(fa));
memset(cnt,0,sizeof(cnt));
memset(siz,0,sizeof(siz));
scanf("%d",&n);root=tot=0;
for(int i=1,x;i<=n;i++){
scanf("%d%d",&opt,&x);
if(opt==1)
ins(root,x);
else if(opt==2)
del(root,x);
else if(opt==3)
printf("%d\n",rank(root,x));
else if(opt==4)
printf("%d\n",query(root,x));
else if(opt==5)
printf("%d\n",pre(root,x));
else
printf("%d\n",suf(root,x));
}
return 0;
}


View Code

by NeighThorn
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: