这题好神呀。lct做法参见:传送门
这里说说splay做法。我们考虑一棵树的dfs序。进点x的时候记下x,出点x的时候记下x+n。则x的子树就是区间[x,x+n]。则操作1就相当于删除一个区间的数,然后把这一整个区间的数插入一个数的后面。x节点所在的根就是dfs序最前面的那个节点。然后就可以做了,不过需要奇怪的splay姿势【再见】
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
#define N 50010
inline int read(){
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*f;
}
int n,m,fa[N<<1],c[N<<1][2],a[N<<1],tot=0,root,h[N],num=0;
bool f[N],blank=0;
struct edge{
int to,next;
}data[N];
inline void add(int x,int y){
data[++num].to=y;data[num].next=h[x];h[x]=num;
}
inline void dfs(int x){
a[++tot]=x;
for(int i=h[x];i;i=data[i].next) dfs(data[i].to);
a[++tot]=x+n;
}
inline void build(int &p,int l,int r){
int mid=l+r>>1;p=a[mid];
if(l<mid) build(c[p][0],l,mid-1),fa[c[p][0]]=p;
if(r>mid) build(c[p][1],mid+1,r),fa[c[p][1]]=p;
}
inline void rotate(int x){
int y=fa[x],z=fa[y],l=x==c[y][1],r=l^1;
if(z) c[z][y==c[z][1]]=x;
fa[c[x][r]]=y;fa[y]=x;fa[x]=z;
c[y][l]=c[x][r];c[x][r]=y;
}
inline void splay(int x,int k){
while(fa[x]!=k){
int y=fa[x],z=fa[y];
if(fa[y]!=k){
if(x==c[y][1]^y==c[z][1]) rotate(x);
else rotate(y);
}rotate(x);
}
}
inline int find(int x){
splay(x,0);while(c[x][0]) x=c[x][0];return x;
}
inline void move(int x,int y){
if(x==y) return;
splay(x,0);splay(x+n,x);
for(int i=y;i;i=fa[i]) if(i==c[x+n][0]) return;
int xx=c[x][0],yy=c[x+n][1];c[x][0]=c[x+n][1]=fa[xx]=fa[yy]=0;
if(xx&&yy){
while(c[yy][0]) yy=c[yy][0];c[yy][0]=xx;fa[xx]=yy;
}if(!y) return;
splay(y,0);int succ=c[y][1];while(c[succ][0]) succ=c[succ][0];
splay(succ,y);c[succ][0]=x;fa[x]=succ;
}
int main(){
// freopen("a.in","r",stdin);
while(~scanf("%d",&n)){
if(!blank) blank=1;else puts("");memset(f,0,sizeof(f));
memset(h,0,sizeof(h));num=0;
memset(fa,0,sizeof(fa));memset(c,0,sizeof(c));
for(int i=1;i<=n;++i){
int x=read();if(!x) f[i]=1;
else add(x,i);
}for(int i=1;i<=n;++i){
if(!f[i]) continue;tot=0;dfs(i);build(root,1,tot);
}m=read();
while(m--){
char op[10];scanf("%s",op+1);int x=read();
if(op[1]=='Q') printf("%d\n",find(x));
else move(x,read());
}
}return 0;
}