题意是箱子套箱子,每次移动箱子x到箱子y里,或询问x最外层的箱子。
这一道题根是固定的,不能换根。
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 50005
using namespace std;
int fa[maxn],ch[maxn][2];
int f[maxn];
bool isroot(int x)
{return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
bool dir(int x)
{return ch[fa[x]][1]==x;}
void rotate(int x)
{
int y=fa[x],z=fa[y];
bool b=dir(x);
int a=ch[x][!b];
if(!isroot(y))
ch[z][dir(y)]=x;
fa[x]=z;ch[x][!b]=y;
fa[y]=x;ch[y][b]=a;
if(a) fa[a]=y;
}
void splay(int x)
{
while(!isroot(x))
{
int y=fa[x];
if(isroot(y)) rotate(x);
else
{
bool b=dir(x),c=dir(y);
if(b^c) {rotate(y);rotate(x);}
else {rotate(x);rotate(x);}
}
}
}
void access(int x)
{
for(int t=0;x;t=x,x=fa[x])
splay(x),ch[x][1]=t;
}
int find_root(int x)
{
access(x);splay(x);
while(ch[x][0]) x=ch[x][0];
return x;
}
void cut(int x)
{
access(f[x]);
splay(x);fa[x]=0;
}
void link(int x,int y)
{
cut(x);
if(!y)return ;
if(find_root(y)==x)
{
splay(x);
fa[x]=f[x];
return ;
}
fa[x]=y;
f[x]=y;
}
char s[10];
void init()
{
memset(f,0,sizeof(f));
memset(fa,0,sizeof(fa));
memset(ch,0,sizeof(ch));
}
int main()
{
int n;
bool fst=1;
while(scanf("%d",&n)!=EOF)
{
if(fst) fst=0;
else puts("");
init();
for(int i=1;i<=n;i++)
{
scanf("%d",&fa[i]);
f[i]=fa[i];
}
int m,x,y;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%s%d",s,&x);
if(s[0]=='Q')
printf("%d\n",find_root(x));
else
{
scanf("%d",&y);
link(x,y);
}
}
}
return 0;
}