简单题,1A
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MAX 30030
#define ls rt<<1
#define rs ls|1
#define m (l+r)>>1
int sum[MAX << 2], sum2[MAX << 2];
int size[MAX], son[MAX], deep[MAX], pre[MAX], top[MAX],val[MAX];
int posx[MAX], head[MAX],posx2[MAX];
int cnt, pos;
struct edge
{
int v, next;
}edg[MAX<<1];
void addedge(int u, int v)
{
edg[cnt].v = v;
edg[cnt].next = head[u];
head[u] = cnt++;
}
void dfs(int u, int p, int d)
{
deep[u] = d;
size[u] = 1;
pre[u] = p;
for (int i = head[u]; i != -1; i = edg[i].next)
{
int v = edg[i].v;
if (v != p)
{
dfs(v,u, d+ 1);
size[u] += size[v];
if (son[u] == -1 || size[v] > size[son[u]])
son[u] = v;
}
}
}
void getpos(int u, int p)
{
top[u] = p;
posx2[pos] = u;
posx[u] = pos++;
if (son[u] == -1)
return;
getpos(son[u], p);
for (int i = head[u]; i != -1; i = edg[i].next)
{
int v = edg[i].v;
if (v != son[u]&&v!=pre[u])
getpos(v, v);
}
}
//线段树
void uprt(int rt)
{
sum[rt] = sum[ls] + sum[rs];
sum2[rt] = max(sum2[ls], sum2[rs]);
}
void build(int l, int r, int rt)
{
if (l == r)
{
sum[rt] = val[posx2[l]];
sum2[rt] = sum[rt];
return;
}
int mid = m;
build(l, mid, ls);
build(mid + 1, r, rs);
uprt(rt);
}
void updata(int q, int val, int l, int r, int rt)
{
if (l == r)
{
sum[rt] = val;
sum2[rt] = val;
return;
}
int mid = m;
if (q <= mid)
updata(q ,val, l, mid, ls);
else
updata(q,val, mid + 1, r, rs);
uprt(rt);
}
int queryS(int L, int R, int l, int r, int rt)
{
if (L <= l&&r <= R)
return sum[rt];
int mid = m;
int ans = 0;
if (L <= mid)
ans = queryS(L, R, l, mid, ls);
if (mid < R)
ans += queryS(L, R, mid + 1, r, rs);
return ans;
}
int queryM(int L, int R, int l, int r, int rt)
{
if (L <= l&&r <= R)
return sum2[rt];
int mid = m;
int ans =-0x7ffffff;
if (L <= mid)
ans = max(ans, queryM(L, R, l, mid, ls));
if (mid < R)
ans = max(ans, queryM(L, R, mid + 1, r, rs));
return ans;
}
int solve(int u, int v,int tg)
{
int fu = top[u], fv = top[v];
int ans;
if (tg)
ans = -0x7ffffff;
else
ans = 0;
while (fu != fv)
{
if (deep[fu] < deep[fv])
{
swap(fu, fv);
swap(u, v);
}
if (tg)
ans = max(ans, queryM(posx[fu], posx[u], 1, pos - 1, 1));
else
ans += queryS(posx[fu], posx[u], 1, pos - 1, 1);
u = pre[fu];
fu = top[u];
}
if (u == v)
{
if (tg)
ans = max(ans, queryM(posx[u], posx[u], 1, pos - 1, 1));
else
ans += queryS(posx[u], posx[u], 1, pos - 1, 1);
return ans;
}
if (deep[u] > deep[v])
swap(u, v);
if (tg)
ans = max(ans, queryM(posx[u], posx[v], 1, pos - 1, 1));
else
ans += queryS(posx[u], posx[v], 1, pos - 1, 1);
return ans;
}
//void gao(int u, int v, int val)
//{
// int fu = top[u], fv = top[v];
// while (fu != fv)
// {
// if (deep[fu] < deep[fv])
// {
// swap(fu, fv);
// swap(u, v);
// }
// updata(posx[fu], posx[u], val, 1, pos - 1, 1);
// u = pre[fu];
// fu = top[fu];
// }
// if (u == v)
// updata(posx[u], posx[u], val, 1, pos - 1, 1);
// else
// {
// if (deep[u] > deep[v])
// swap(u, v);
// updata(posx[u], posx[v], val, 1, pos - 1, 1);
// }
//}
void init()
{
cnt = 0;
pos = 1;
memset(son, -1, sizeof(son));
memset(head, -1, sizeof(head));
}
int main()
{
int n;
while (~scanf("%d", &n))
{
int a, b;
init();
for (int i = 1; i < n; i++)
{
scanf("%d%d", &a, &b);
addedge(a, b);
addedge(b, a);
}
for (int i = 1; i <= n; i++)
{
scanf("%d", &val[i]);
}
dfs(1, 1, 0);
getpos(1, 1);
build(1, pos - 1, 1);
char str[10];
int q;
scanf("%d", &q);
while (q--)
{
scanf("%s%d%d", str,&a,&b);
if (str[0] == 'C')
{
updata(posx[a], b, 1, pos - 1, 1);
}
else
if (str[1] == 'M')
printf("%d\n", solve(a, b, 1));
else
printf("%d\n", solve(a, b, 0));
}
}
}