rt
#include <bits/stdc++.h>
#define max(a, b) ((a) > (b) ? (a) : (b))
#define INF 2147483647
const int N = 1e5;
struct edge {
int nxt, to;
} e[2 * N + 5];
struct node {
int hson, siz, fa, dep, top, dfn;
} t[N + 5];
int n, tot, head[N + 5], cnt, rnk[N + 5], w[N + 5];
struct xdtree{
int sum[4 * N + 5], mx[4 * N + 5];
void pushup(int x) {sum[x] = sum[x << 1] + sum[x << 1 | 1], mx[x] = max(mx[x << 1], mx[x << 1 | 1]);}
void build(int x, int l, int r) {
if (l == r) {
sum[x] = mx[x] = w[rnk[l]];
return;
}
int mid = (l + r) >> 1;
build(x << 1, l, mid);
build(x << 1 | 1, mid + 1, r);
pushup(x);
}
int querysum(int x, int s, int t, int l, int r) {
if (l <= s && t <= r) return sum[x];
int mid = (s + t) >> 1, res = 0;
if (mid >= l) res += querysum(x << 1, s, mid, l, r);
if (mid < r) res += querysum(x << 1 | 1, mid + 1, t, l, r);
return res;
}
int querymx(int x, int s, int t, int l, int r) {
if (l <= s && t <= r) return mx[x];
int mid = (s + t) >> 1, res = -INF;
if (mid >= l) res = max(res, querymx(x << 1, s, mid, l, r));
if (mid < r) res = max(res, querymx(x << 1 | 1, mid + 1, t, l, r));
return res;
}
void update(int x, int l, int r, int u, int k) {
if (l == r) {
sum[x] = mx[x] = k;
return;
}
int mid = (l + r) >> 1;
if (u <= mid) update(x << 1, l, mid, u, k);
else update(x << 1 | 1, mid + 1, r, u, k);
pushup(x);
}
} st;
void add(int u, int v) {
e[++tot] = {head[u], v};
head[u] = tot;
}
void dfs1(int x, int fthr) {
t[x] = {0, 1, fthr, t[fthr].dep + 1, 0, 0};
for (int i = head[x]; i; i = e[i].nxt) {
if (t[e[i].to].dep) continue;
dfs1(e[i].to, x);
t[x].siz += t[e[i].to].siz;
if (t[t[x].hson].siz < t[e[i].to].siz) t[x].hson = e[i].to;
}
}
void dfs2(int x, int k) {
t[x].top = k;
t[x].dfn = ++cnt;
rnk[cnt] = x;
if (!t[x].hson) return;
dfs2(t[x].hson, k);
for (int i = head[x]; i; i = e[i].nxt)
if (e[i].to != t[x].hson && e[i].to != t[x].fa) dfs2(e[i].to, e[i].to);
}
int qmax(int u, int v) {
int res = -INF;
while (t[u].top != t[v].top) {
if (t[t[u].top].dep < t[t[v].top].dep)
std::swap(u, v);
res = max(res, st.querymx(1, 1, n, t[t[u].top].dfn, t[u].dfn));
u = t[t[u].top].fa;
}
if (t[u].dfn > t[v].dfn) std::swap(u, v);
res = max(res, st.querymx(1, 1, n, t[u].dfn, t[v].dfn));
return res;
}
int qsum(int u, int v) {
int res = 0;
while (t[u].top != t[v].top) {
if (t[t[u].top].dep < t[t[v].top].dep)
std::swap(u, v);
res = res + st.querysum(1, 1, n, t[t[u].top].dfn, t[u].dfn);
u = t[t[u].top].fa;
}
if (t[u].dfn > t[v].dfn) std::swap(u, v);
res = res + st.querysum(1, 1, n, t[u].dfn, t[v].dfn);
return res;
}
int main() {
scanf("%d", &n);
for (int i = 1; i < n; i++) {
int u, v; scanf("%d%d", &u, &v);
add(u, v);
add(v, u);
}
for (int i = 1; i <= n; i++)
scanf("%d", w + i);
dfs1(1, 0);
dfs2(1, 1);
st.build(1, 1, n);
int q; scanf("%d", &q);
while (q--) {
char typ[10]; scanf("%s", typ + 1);
int x, y; scanf("%d%d", &x, &y);
if (!strcmp(typ + 1,"CHANGE")) st.update(1, 1, n, t[x].dfn, y);
if (!strcmp(typ + 1, "QMAX")) printf("%d\n", qmax(x, y));
if (!strcmp(typ + 1, "QSUM")) printf("%d\n", qsum(x, y));
}
}
求dalao调