主♂席♂树♂裸♂题
https://oj.changjun.com.cn/problem/detail/pid/2425
// It is made by XZZ
#include<cstdio>
#include<algorithm>
#define il inline
#define rg register
#define vd void
#define sta static
typedef long long ll;
il int gi(){
rg int x=0,f=1;rg char ch=getchar();
while(ch<'0'||ch>'9')f=ch=='-'?-1:f,ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
const int _=30001;
int n,w[_],dfn[_],ed[_];
namespace cmt{
#define mid ((l+r)>>1)
typedef const int& ci;
const int __=_*100;
int index,rt[10001],ls[__],rs[__],sum[__];
il vd update(int&x,int l,int r,ci o,ci p){
if(!x)x=++index;sum[x]+=o;
if(l==r)return;
if(p<=mid)update(ls[x],l,mid,o,p);
else update(rs[x],mid+1,r,o,p);
}
il vd Update(int x,int p,int o){for(rg int i=p;i<=10000;i+=i&-i)update(rt[i],1,n,o,x);}
il int query(int x,int l,int r,int L,int R){
if(!sum[x])return 0;
if(L<=l&&r<=R)return sum[x];
if(L<=mid)
if(mid<R)return query(ls[x],l,mid,L,R)+query(rs[x],mid+1,r,L,R);
else return query(ls[x],l,mid,L,R);
else return query(rs[x],mid+1,r,L,R);
}
il int Query(int a,int b,int l,int r){
int ret=0;
for(rg int i=b;i;i-=i&-i)ret+=query(rt[i],1,n,l,r);
for(rg int i=a-1;i;i-=i&-i)ret-=query(rt[i],1,n,l,r);
//printf("%d %d %d %d %d
",a,b,l,r,ret);
return ret;
}
#undef mid
}
namespace tree{
int fir[_],nxt[_*2],dis[_*2];
il vd link(int x,int y){
sta int id;
nxt[++id]=fir[x],fir[x]=id,dis[id]=y;
nxt[++id]=fir[y],fir[y]=id,dis[id]=x;
}
il vd dfs(int x,int fa=-1){
dfn[x]=++dfn[0];
for(int i=fir[x];i;i=nxt[i])
if(fa!=dis[i])dfs(dis[i],x);
ed[x]=dfn[0];
}
il vd prepare(){
dfs(1);
for(rg int i=1;i<=n;++i)cmt::Update(dfn[i],w[i],1);
}
}
int main(){
#ifdef xzz
freopen("huaji.in","r",stdin);
freopen("huaji.out","w",stdout);
#endif
n=gi();
for(rg int i=1;i<=n;++i)w[i]=gi();
for(rg int i=1;i<n;++i)tree::link(gi(),gi());
tree::prepare();
int q=gi(),o,a,b,u;
while(q--){
o=gi();
if(o==1){
u=gi(),a=gi();
int l=1,r=10000,mid;
while(l<r){
mid=(l+r)>>1;
if(cmt::Query(1,mid,dfn[u],ed[u])<a)l=mid+1;
else r=mid;
}
printf("%d
",l);
}else if(o==2){
u=gi(),a=gi(),b=gi();
printf("%d
",cmt::Query(a,b,dfn[u],ed[u]));
}else if(o==3){
u=gi(),a=gi();
cmt::Update(dfn[u],w[u],-1);
cmt::Update(dfn[u],w[u]=a,1);
}else puts("FA♂Q");
}
return 0;
}