1 #include <cstdio>
2 #include <algorithm>
3 #include <cstring>
4 using namespace std;
5
6 const int size = 30000;
7 int num[size+10] , fa[size+10] , depth[size+10] , son[size+10] , top[size+10] , var[size+10] , pos[size+10];
8 struct graph {
9 int Next;
10 int to;
11 };
12 graph edge[size*2+10];
13 int head[size+10];
14 struct seg_tree {
15 int L , R;
16 int maxvar , sum;
17 };
18 seg_tree tree[size<<2];
19 int cnt , tot;
20 int res_sum , res_max;
21
22 void addEdge( int u , int v ) {
23 edge[cnt].to = v;
24 edge[cnt].Next = head[u];
25 head[u] = cnt++;
26 }
27
28 void dfs( int u ) {
29 num[u] = 1;
30 for ( int i = head[u] ; ~i ; i = edge[i].Next ) {
31 int v = edge[i].to;
32 if ( v!=fa[u] ) {
33 fa[v] = u;
34 depth[v] = depth[u] + 1;
35 dfs( v );
36 num[u] += num[v];
37 if ( son[u]==-1 || num[v] > num[son[u]] ) {
38 son[u] = v;
39 }
40 }
41 }
42 }
43
44 void redfs( int u , int rt ) {
45 top[u] = rt;
46 pos[u] = ++ tot;
47 if ( son[u]==-1 ) {
48 return;
49 }
50 if ( ~son[u] ) {
51 redfs( son[u] , rt );
52 }
53 for ( int i = head[u] ; ~i ; i = edge[i].Next ) {
54 int v = edge[i].to;
55 if ( v!=son[u] && v!=fa[u] ) {
56 redfs( v , v );
57 }
58 }
59 }
60
61 void build( int rt , int L , int R ) {
62 int M = ( L + R ) >> 1;
63 tree[rt].L = L;
64 tree[rt].R = R;
65 if ( L==R ) {
66 tree[rt].maxvar = tree[rt].sum = var[L];
67 return;
68 }
69 build( rt<<1 , L , M );
70 build( rt<<1|1 , M+1 , R );
71 tree[rt].maxvar = max( tree[rt<<1].maxvar , tree[rt<<1|1].maxvar );
72 tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;
73 }
74
75 void update( int rt , int p , int temp ) {
76 int M = ( tree[rt].L + tree[rt].R ) >> 1;
77 if ( tree[rt].L == tree[rt].R && tree[rt].L == p ) {
78 tree[rt].maxvar = tree[rt].sum = temp;
79 return;
80 }
81 if ( p<=M ) {
82 update( rt<<1 , p , temp );
83 } else {
84 update( rt<<1|1 , p , temp );
85 }
86 tree[rt].maxvar = max( tree[rt<<1].maxvar , tree[rt<<1|1].maxvar );
87 tree[rt].sum = tree[rt<<1].sum + tree[rt<<1|1].sum;
88 }
89
90 void query( int rt , int L , int R ) {
91 int M = ( tree[rt].L + tree[rt].R ) >> 1;
92 if ( L==tree[rt].L && tree[rt].R==R) {
93 res_max = max( res_max , tree[rt].maxvar );
94 res_sum += tree[rt].sum;
95 return;
96 }
97 if ( R<=M ) {
98 query( rt<<1 , L , R );
99 } else if ( L>=M+1 ) {
100 query( rt<<1|1 , L , R );
101 } else {
102 query( rt<<1 , L , M );
103 query( rt<<1|1 , M+1 , R );
104 }
105 }
106
107 void solve( int u , int v ) {
108 res_sum = 0;
109 res_max = -11111111;
110 int tu = top[u];
111 int tv = top[v];
112 while ( tu!=tv ) {
113 if ( depth[tu]<depth[tv] ) {
114 swap(tu,tv);
115 swap(u,v);
116 }
117 query( 1 , pos[tu] , pos[u] );
118 u = fa[tu];
119 tu = top[u];
120 }
121 if ( depth[u] > depth[v] ) {
122 swap(u,v);
123 }
124 query( 1 , pos[u] , pos[v] );
125 }
126
127 int main( ) {
128 int n;
129 while ( ~scanf("%d",&n) ) {
130 memset( head , -1 , sizeof(head) );
131 cnt = 0;
132 int u , v;
133 for ( int i = 1 ; i<=n-1 ; ++i ) {
134 scanf("%d %d",&u,&v);
135 addEdge(u,v);
136 addEdge(v,u);
137 }
138 memset( fa , -1 , sizeof(fa) );
139 fa[1] = 1;
140 memset( son , -1 , sizeof(son) );
141 depth[1] = 1;
142 dfs(1);
143 tot = 0;
144 redfs(1,1);
145 for ( int i = 1 ; i<=n ; ++i ) {
146 int x;
147 scanf("%d",&x);
148 var[ pos[i] ] = x;
149 }
150 build( 1 , 1 , tot );
151 int q;
152 scanf("%d",&q);
153 while ( q-- ) {
154 char str[10];
155 scanf("%s %d %d",str,&u,&v);
156 if ( str[0]=='C' ) {
157 update(1,pos[u],v);//结点u的值更新为v
158 } else if ( str[3]=='X' ) {
159 solve(u,v);
160 printf("%d
",res_max);//查询路径从U->V的最大值
161 } else {
162 solve(u,v);
163 printf("%d
",res_sum);//求路径从U->V的和值
164 }
165 }
166 }
167 return 0;
168 }