求调,感激不尽。
#include<bits/stdc++.h>
#define int long long
#define pb push_back
#define il inline
#define re register
#define pii pair<int,int>
#define fs first
#define sc second
#define md(rt) (tree[rt].l+tree[rt].r>>1)
#define l(rt) (rt<<1)
#define r(rt) (rt<<1|1)
using namespace std;
il int read()
{
re int x=0;
re int ff=1;
re char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')
ff=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*ff;
}
const int N=3e4+6;
struct edge{
int v,next;
};
edge e[N<<1];
struct seg_ment{
int l,r,mx,z;
};
seg_ment tree[N<<2];
int n,f[N],top[N],bh[N],d[N],sz[N],mp[N],son[N],w[N],head[N],k,cnt,q;
il void add(re int u,re int v)
{
e[++k].v=v;
e[k].next=head[u];
head[u]=k;
return;
}
il void dfs1(re int u,re int fa)
{
f[u]=fa;
sz[u]=1;
d[u]=d[fa]+1;
for(re int i=head[u];i;i=e[i].next){
re int v=e[i].v;
if(v==fa)
continue;
dfs1(v,u);
sz[u]+=sz[v];
if(sz[son[u]]<sz[v])
son[u]=v;
}
return;
}
il void dfs2(re int u,re int fa)
{
if(son[u]){
top[son[u]]=top[u];
bh[son[u]]=++cnt;
mp[cnt]=son[u];
dfs2(son[u],u);
}
for(re int i=head[u];i;i=e[i].next){
re int v=e[i].v;
if(v==fa||v==son[u])
continue;
top[v]=v;
bh[v]=++cnt;
mp[cnt]=v;
dfs2(v,u);
}
return;
}
il void push_up(re int rt)
{
tree[rt].z=tree[l(rt)].z+tree[r(rt)].z;
tree[rt].mx=max(tree[l(rt)].mx,tree[r(rt)].mx);
return;
}
il void build(re int rt,re int l,re int r)
{
tree[rt].l=l;
tree[rt].r=r;
if(l==r){
tree[rt].mx=tree[rt].z=w[mp[l]];
return;
}
int mid=md(rt);
build(l(rt),l,mid);
build(r(rt),mid+1,r);
push_up(rt);
return;
}
il void updata(re int rt,re int x,re int z)
{
if(tree[rt].l==tree[rt].r){
tree[rt].mx=tree[rt].z=z;
return;
}
int mid=md(rt);
if(x<=mid)
updata(l(rt),x,z);
else
updata(r(rt),x,z);
push_up(rt);
return;
}
il int query_sum(re int rt,re int l,re int r)
{
if(l<=tree[rt].l&&tree[rt].r<=r)
return tree[rt].z;
int mid=md(rt),awa=0;
if(l<=mid)
awa+=query_sum(l(rt),l,r);
if(r>mid)
awa+=query_sum(r(rt),l,r);
return awa;
}
il int query_mx(re int rt,re int l,re int r)
{
if(l<=tree[rt].l&&tree[rt].r<=r)
return tree[rt].mx;
int mid=md(rt),awa=-1e5;
if(l<=mid)
awa=max(awa,query_mx(l(rt),l,r));
if(r>mid)
awa=max(awa,query_mx(r(rt),l,r));
return awa;
}
il int get(re int flag,re int x,re int y)
{
int awa=(flag?0:-1e5),fx=top[x],fy=top[y];
while(fx!=fy){
if(d[fx]>d[fy])
swap(fx,fy),swap(x,y);
if(flag)
awa+=query_sum(1,bh[fy],bh[y]);
else
awa=max(awa,query_mx(1,bh[fy],bh[y]));
// printf("%lld-%lld\n",bh[fy],bh[y]);
y=f[fy],fy=top[y];
}
if(d[x]>d[y])
swap(x,y);
if(flag)
awa+=query_sum(1,bh[x],bh[y]);
else
awa=max(awa,query_mx(1,bh[x],bh[y]));
// printf("%lld-%lld\n",bh[x],bh[y]);
return awa;
}
signed main()
{
n=read();
for(re int i=1;i<n;i++){
re int u,v;
u=read();
v=read();
add(u,v);
add(v,u);
}
for(re int i=1;i<=n;i++)
w[i]=read();
dfs1(1,0);
top[1]=1;
bh[1]=++cnt;
mp[cnt]=1;
dfs2(1,0);
build(1,1,n);
q=read();
for(;q;q--){
char c;
cin>>c;cin>>c;
int u,v;
u=read();
v=read();
if(c=='H')
updata(1,u,v);
else if(c=='M')
printf("%lld\n",get(0,u,v));
else
printf("%lld\n",get(1,u,v));
}
return 0;
}