您的位置:首页 > 其它

平衡树

2016-04-15 08:17 423 查看
#include<iostream>
#include<cstdio>
#include<map>
using namespace std;
map<int,int> bh;
int key[100010];
int fa[100010];
int ch[100010][2];
int sz[100010];
int cnt[100010];
int t1,t2,tot,root;
int inf=2147483646;
bool dir(int x){return x==ch[fa[x]][1];}
void find_pre(int i,int x){
if(key[i]==0)
return ;
if(key[i]<x){
t1=key[i];
find_pre(ch[i][1],x);
}
else
find_pre(ch[i][0],x);
}
void find_nxt(int i,int x){
if(key[i]==0)
return ;
if(key[i]>x){
t2=key[i];
find_nxt(ch[i][0],x);
}
else
find_nxt(ch[i][1],x);
}
void up(int x){
sz[0]=0;
sz[x]=sz[ch[x][0]]+sz[ch[x][1]]+cnt[x];
}
void rotate(int x){
bool b=dir(x);int y=fa[x];
int z=fa[y];int a=ch[x][!b];
if(z==0)
root=x;
else
ch[z][dir(y)]=x;
fa[x]=z;fa[y]=x;
ch[x][!b]=y;ch[y][b]=a;
if(a!=0)
fa[a]=y;
up(y);up(x);
if(z!=0)up(z);
}
void splay(int x,int i){
bool b,c;
while(fa[x]!=i){
int y=fa[x];int z=fa[y];
if(z==i)    rotate(x);
else{
b=dir(x),c=dir(y);
if(b^c) {   rotate(x);rotate(x);}
else    {   rotate(y);rotate(x);}
}
}
if(i==0)    root=x;
}
void insert(int k,int x,int last){
if(x==key[k]){
cnt[k]++;
up(k);  up(fa[k]);
return ;
}
if(!k){
k=++tot;
bh[x]=k;
key[k]=x;
cnt[k]=1;
sz[k]=1;
fa[k]=last;
if(key[k]<key[last])    ch[last][0]=k;
else ch[last][1]=k;
splay(k,0);
return ;
}
if(x<key[k]){
insert(ch[k][0],x,k);
up(k);
return ;
}
else{
insert(ch[k][1],x,k);
up(k);
return ;
}
}

void del(int y){
int x=bh[y];
splay(x,0);
cnt[x]--;sz[x]--;
if(cnt[x]==0){
sz[0]=0;
if(sz[ch[x][0]]==0){
root=ch[x][1];
fa[ch[x][1]]=0;
}
else if(sz[ch[x][1]]==0){
root=ch[x][0];
fa[ch[x][0]]=0;
}
else{
t1=-inf;
find_pre(root,y);
int h=bh[t1];
splay(h,x);
root=h;
fa[h]=0;
ch[h][1]=ch[x][1];
fa[ch[x][1]]=h;
up(root);
}
key[x]=0;
fa[x]=0;
ch[x][0]=0;
ch[x][1]=0;
}
}
int rank_to_num(int dq,int rank){
sz[0]=0;
if(sz[ch[dq][0]]>=rank)
return rank_to_num(ch[dq][0],rank);
if(sz[ch[dq][0]]+cnt[dq]<rank)
return rank_to_num(ch[dq][1],rank-sz[ch[dq][0]]-cnt[dq]);
return key[dq];
}
int main()
{
int n,x,y;scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&x,&y);
if(x==1){
insert(root,y,0);
up(root);
}
if(x==2)
del(y);
if(x==3){
sz[0]=0;
splay(bh[y],0);
printf("%d\n",sz[ch[root][0]]+1);
}
if(x==4)
printf("%d\n",rank_to_num(root,y));
if(x==5){
t1=y;
find_pre(root,y);
printf("%d\n",t1);
}
if(x==6){
t2=inf;
find_nxt(root,y);
printf("%d\n",t2);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: