借鉴了别人的代码……
//By SiriusRen
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 66666
struct Blocks{
int a[210],size;
void Insert(int x){
++size;int i;
for(i=size;i>1&&a[i-1]>x;i--)a[i]=a[i-1];
a[i]=x;
}
void Modify(int x,int y){
int temp=lower_bound(a+1,a+1+size,x)-a;
for(;temp<size&&a[temp+1]<y;temp++)a[temp]=a[temp+1];
for(;temp>1&&a[temp-1]>y;temp--)a[temp]=a[temp-1];
a[temp]=y;
}
int Query(int x){
return size-(upper_bound(a+1,a+1+size,x)-a)+1;
}
}blocks[10500];
int n,m,op,xx,yy,block,cnt,ans,a[N],fa[N],belong[N];
int first[N],bfirst[N],next[N*2],v[N*2],tot;
void add(int Head[],int x,int y){v[tot]=y,next[tot]=Head[x],Head[x]=tot++;}
void DFS(int x){
if(blocks[belong[fa[x]]].size==block)
blocks[belong[x]=++cnt].Insert(a[x]),add(bfirst,belong[fa[x]],cnt);
else blocks[belong[x]=belong[fa[x]]].Insert(a[x]);
for(int i=first[x];~i;i=next[i])
if(v[i]!=fa[x])fa[v[i]]=x,DFS(v[i]);
}
void bdfs(int x,int y){
ans+=blocks[x].Query(y);
for(int i=bfirst[x];~i;i=next[i])bdfs(v[i],y);
}
void dfs(int x,int y){
if(a[x]>y)ans++;
for(int i=first[x];~i;i=next[i])
if(v[i]!=fa[x]){
if(belong[v[i]]==belong[x])dfs(v[i],y);
else bdfs(belong[v[i]],y);
}
}
int main(){
memset(first,-1,sizeof(first)),memset(bfirst,-1,sizeof(bfirst));
scanf("%d",&n);
for(int i=1;i<n;i++)
scanf("%d%d",&xx,&yy),add(first,xx,yy),add(first,yy,xx);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
block=int(sqrt(n)+0.5),DFS(1);
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d%d%d",&op,&xx,&yy),xx^=ans,yy^=ans;
if(!op){ans=0;dfs(xx,yy);printf("%d\n",ans);}
else if(op==1)blocks[belong[xx]].Modify(a[xx],yy),a[xx]=yy;
else{
a[++n]=yy,add(first,xx,n),fa[n]=xx;
if(blocks[belong[xx]].size==block)
blocks[belong[n]=++cnt].Insert(a[n]),add(bfirst,belong[xx],cnt);
else blocks[belong[n]=belong[xx]].Insert(a[n]);
}
}
}