Each node has a color, white or black, and a weight.
We will ask you to perfrom some instructions of the following form:
- 0 u : ask for the maximum weight among the nodes which are connected to u, two nodes are connected iff all the node on the path from u to v (inclusive u and v) have a same color.
- 1 u : toggle the color of u(that is, from black to white, or from white to black).
- 2 u w: change the weight of u to w.
For each query operation, output the corresponding result.
#include<cstdio>
#define G *++ptr
const int N=100007;
char buf[N*100],*ptr=buf-1;
int _(){
int x=0,c=G,f=1;
while(c<48)c==‘-‘&&(f=-1),c=G;
while(c>47)x=x*10+c-48,c=G;
return x*f;
}
int ch[N*6][5],n;
int col[N];
#define lc ch][0
#define rc ch][1
#define fa ch][2
#define val ch][3
#define mxv ch][4
int max(int a,int b){return a>b?a:b;}
void up(int x){
x[mxv]=max(x[val],max(x[lc][mxv],x[rc][mxv]));
}
void rot(int x){
int f=x[fa],g=f[fa],d=(x!=f[lc]);
if(g)g[ch][g[lc]!=f]=x;
x[fa]=g;
(f[ch][d]=x[ch][d^1])[fa]=f;
(x[ch][d^1]=f)[fa]=x;
up(f),up(x);
}
void sp(int x,int y=0){
while(x[fa]!=y){
int f=x[fa];
if(f[fa]!=y)rot((f[lc]==x)==(f[fa][lc]==f)?f:x);
rot(x);
}
}
int gl(int x){
sp(x);
while(x[lc])x=x[lc];
sp(x);
return x;
}
void lk(int x,int y){
sp(x);sp(y);
int z=y[rc],xr=x+n*3;
(y[rc]=x)[fa]=y;
up(y);
sp(xr);
(xr[rc]=z)[fa]=xr;
up(xr);
}
void ct(int x){
int xr=x+n*3;
sp(x);
int l=x[lc];
l[fa]=x[lc]=0;
up(x);
sp(xr);
int r=xr[rc];
r[fa]=xr[rc]=0;
up(xr);
r=gl(r);
(r[lc]=l)[fa]=r;
up(r);
}
int F(int w,int t){
return w+(t+1)*n;
}
void init(){
const int inf=0x3f3f3f3f;
0[val]=0[mxv]=-inf;
for(int i=1;i<=n;++i)col[i]=_();
for(int i=1;i<=n;++i)i[val]=i[mxv]=_();
for(int i=n+1;i<=n*6;++i)i[val]=i[mxv]=-inf;
for(int i=1;i<=n*3;++i)(i[rc]=i+n*3)[fa]=i,up(i);
}
#undef fa
int es[N*2],enx[N*2],e0[N],ep=2;
int fa[N],sz[N],son[N],dep[N],top[N];
void f1(int w,int pa){
sz[w]=1;
dep[w]=dep[fa[w]=pa]+1;
lk(F(w,col[w]),w);
for(int i=e0[w];i;i=enx[i]){
int u=es[i];
if(u!=pa){
f1(u,w);
lk(u,F(w,col[u]));
sz[w]+=sz[u];
if(sz[u]>sz[son[w]])son[w]=u;
}
}
}
void f2(int w,int tp){
top[w]=tp;
if(son[w])f2(son[w],tp);
for(int i=e0[w];i;i=enx[i]){
int u=es[i];
if(u!=fa[w]&&u!=son[w])f2(u,u);
}
}
int up(int x,int y){
int a=top[x],b=top[y];
while(a!=b){
x=fa[a];
if(x==y)return a;
a=top[x];
}
return son[y];
}
int main(){
fread(buf,1,sizeof(buf),stdin)[buf]=0;
n=_();
for(int i=1,a,b;i<n;++i){
a=_();b=_();
es[ep]=b;enx[ep]=e0[a];e0[a]=ep++;
es[ep]=a;enx[ep]=e0[b];e0[b]=ep++;
}
init();
f1(1,0);f2(1,1);
for(int q=_();q;--q){
int o=_(),w=_();
if(o==0){
int l=gl(w);
if(l>n)w=up(w,(l-1)%n+1);
else w=1;
sp(w);
sp(w+n*3,w);
printf("%d\n",max(w[val],(w+n*3)[lc][mxv]));
}else if(o==1){
ct(F(w,col[w]));
lk(F(w,col[w]^1),w);
if(w!=1){
int f=fa[w];
ct(w);
lk(w,F(f,col[w]^1));
}
col[w]^=1;
}else{
sp(w);
w[val]=_();
up(w);
}
}
return 0;
}