Description
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.
Input
The first line contains a number n denoted how many nodes in the tree(1 ≤ n ≤ 105). The next n - 1 lines, each line has two numbers (u, v) describe a edge of the tree(1 ≤ u, v ≤ n).
The next 2 lines, each line contains n number, the first line is the initial color of each node(0 or 1), and the second line is the initial weight, let's say Wi, of each node(|Wi| ≤ 109).
The next line contains a number m denoted how many operations we are going to process(1 ≤ m ≤ 105). The next m lines, each line describe a operation (t, u) as we mentioned above(0 ≤ t ≤ 2, 1 ≤ u ≤ n, |w| ≤ 109).
Output
For each query operation, output the corresponding result.
Sample Input
1 2
1 3
1 4
1 5
0 1 1 1 1
1 2 3 4 5
3
0 1
1 1
0 1
Sample Output
5
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 #include<set> 7 using namespace std; 8 char ch; 9 bool ok; 10 void read(int &x){ 11 for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') ok=1; 12 for (x=0;isdigit(ch);x=x*10+ch-'0',ch=getchar()); 13 if (ok) x=-x; 14 } 15 const int maxn=100005; 16 const int maxm=200005; 17 int n,q,op,a,b,v,tot,now[maxn],son[maxm],pre[maxm],fa[maxn],col[maxn]; 18 struct lct{ 19 int id,fa[maxn],son[maxn][2],val[maxn],maxv[maxn]; 20 multiset<int> rest[maxn]; 21 int which(int x){return son[fa[x]][1]==x;} 22 bool isroot(int x){return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;} 23 void update(int x){ 24 maxv[x]=val[x]; 25 if (!rest[x].empty()) maxv[x]=max(maxv[x],*rest[x].rbegin()); 26 if (son[x][0]) maxv[x]=max(maxv[x],maxv[son[x][0]]); 27 if (son[x][1]) maxv[x]=max(maxv[x],maxv[son[x][1]]); 28 } 29 void rotate(int x){ 30 int y=fa[x],z=fa[y],d=which(x),dd=which(y); 31 fa[son[x][d^1]]=y,son[y][d]=son[x][d^1],fa[x]=fa[y]; 32 if (!isroot(y)) son[z][dd]=x; 33 fa[y]=x,son[x][d^1]=y,update(y),update(x); 34 } 35 void splay(int x){ 36 while (!isroot(x)){ 37 if (isroot(fa[x])) rotate(x); 38 else if (which(x)==which(fa[x])) rotate(fa[x]),rotate(x); 39 else rotate(x),rotate(x); 40 } 41 } 42 void access(int x){ 43 for (int p=0;x;x=fa[x]){ 44 splay(x); 45 if (son[x][1]) rest[x].insert(maxv[son[x][1]]); 46 if (p) rest[x].erase(rest[x].find(maxv[p])); 47 son[x][1]=p,update(p=x); 48 } 49 } 50 void link(int x,int y){ 51 if (!y) return; 52 access(y),splay(y),splay(x),fa[x]=y,son[y][1]=x,update(y); 53 } 54 void cut(int x,int y){ 55 if (!y) return; 56 access(x),splay(x),fa[son[x][0]]=0,son[x][0]=0,update(x); 57 } 58 int find_root(int x){for (access(x),splay(x);son[x][0];x=son[x][0]); return x;} 59 void query(int x){ 60 int t=find_root(x); splay(t); 61 printf("%d ",col[t]==id?maxv[t]:maxv[son[t][1]]); 62 } 63 void modify(int x,int v){access(x),splay(x),val[x]=v,update(x);} 64 }T[2]; 65 void put(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;} 66 void add(int a,int b){put(a,b),put(b,a);} 67 void dfs(int u){ 68 for (int p=now[u],v=son[p];p;p=pre[p],v=son[p]) 69 if (v!=fa[u]) fa[v]=u,T[col[v]].link(v,u),dfs(v); 70 } 71 int main(){ 72 read(n),T[0].id=0,T[1].id=1; 73 for (int i=1;i<n;i++) read(a),read(b),add(a,b); 74 for (int i=1;i<=n;i++) read(col[i]); 75 for (int i=1;i<=n;i++) read(T[0].val[i]),T[0].maxv[i]=T[0].val[i]; 76 for (int i=1;i<=n;i++) T[1].maxv[i]=T[1].val[i]=T[0].val[i]; 77 dfs(1); 78 for (read(q);q;q--){ 79 read(op),read(a); 80 if (op==0) T[col[a]].query(a); 81 else if (op==1) T[col[a]].cut(a,fa[a]),col[a]^=1,T[col[a]].link(a,fa[a]); 82 else read(v),T[0].modify(a,v),T[1].modify(a,v); 83 } 84 return 0; 85 }