您的位置:首页 > 其它

bzoj 2733 [HNOI2012]永无乡 splay启发式合并

2016-12-08 08:38 302 查看
splay启发式合并

#include <bits/stdc++.h>
using namespace std;
#define N 110000
#define which(x) (ch[fa[x]][1]==x)
int n,m,Q;
char s[11];
int ft
,root
,val
;
int fa
,ch
[2],size
;
int find(int x){return ft[x]==x ? x:ft[x]=find(ft[x]);}
void pushup(int x)
{size[x]=size[ch[x][0]]+size[ch[x][1]]+1;}
void rotate(int x)
{
int y=fa[x],k=which(x);
ch[y][k]=ch[x][k^1];
ch[fa[y]][which(y)]=x;
ch[x][k^1]=y;

fa[x]=fa[y];fa[y]=x;
fa[ch[y][k]]=y;

pushup(y);pushup(x);
}
void splay(int x)
{
while(fa[x])
{
int y=fa[x];
if(!fa[y])rotate(x);
else
{
if(which(x)^which(y))
rotate(x);
else rotate(y);
rotate(x);
}
}
root[find(x)]=x;
}
void insert(int x,int y)
{
ch[x][0]=ch[x][1]=0;size[x]=1;
while(1)
{
if(val[x]<val[y])
{
if(!ch[y][0])
{fa[x]=y,ch[y][0]=x;size[y]++;break;}
y=ch[y][0];
}
else
{
if(!ch[y][1])
{fa[x]=y,ch[y][1]=x;size[y]++;break;}
y=ch[y][1];
}
}
splay(x);
}
void dfs(int x,int y)
{
if(!x)return;
dfs(ch[x][0],y);
dfs(ch[x][1],y);
insert(x,root[y]);
}
void merge(int x,int y)
{
x=find(x);y=find(y);
if(x==y)return;
ft[x]=y;
dfs(root[x],y);
}
int find(int x,int K)
{
if(size[ch[x][0]]+1==K)
return x;
if(size[ch[x][0]]>=K)
return find(ch[x][0],K);
return find(ch[x][1],K-size[ch[x][0]]-1);
}
int main()
{
//freopen("tt.in","r",stdin);
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&val[i]);
for(int i=1;i<=n;i++)
ft[i]=i,root[i]=i,size[i]=1;
for(int i=1,x,y;i<=m;i++)
{
scanf("%d%d",&x,&y);
merge(x,y);
}
scanf("%d",&Q);
for(int x,y,K;Q--;)
{
scanf("%s",s+1);
if(s[1]=='B')
{
scanf("%d%d",&x,&y);
merge(x,y);
}
else
{
scanf("%d%d",&x,&K);
splay(x);
if(size[x]<K){puts("-1");continue;}
printf("%d\n",find(x,K));
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: