代码:
const int INF=(1<<29);
const int ma=200005;
struct Node
{
int v;
int nxt;
};
Node node[ma<<1];
int t[ma<<2],ans[ma<<2];
int head[ma],a[ma],wt[ma],id[ma],fa[ma],dep[ma],size[ma],son[ma],top[ma],mx[ma];
int n;
int idx,tot;
inline void add(int u,int v)
{
node[++idx].v=v;
node[idx].nxt=head[u];
head[u]=idx;
}
inline int ls(int p)
{
return p<<1;
}
inline int rs(int p)
{
return p<<1|1;
}
inline void PushUp(int p)
{
ans[p]=ans[ls(p)]+ans[rs(p)];
mx[p]=max(mx[ls(p)],mx[rs(p)]);
}
inline void Build(int p,int l,int r)
{
t[p]=0;
if(l==r)
{
ans[p]=mx[p]=wt[l];
return;
}
int mid=(l+r)>>1;
Build(ls(p),l,mid);
Build(rs(p),mid+1,r);
PushUp(p);
}
inline void Updata(int nl,int nr,int l,int r,int p,int k)
{
if(nl<=l && r<=nr)
{
ans[p]=mx[p]=k;
return;
}
int mid=(l+r)>>1;
if(nl<=mid)
{
Updata(nl,nr,l,mid,ls(p),k);
}
if(nr>mid)
{
Updata(nl,nr,mid+1,r,rs(p),k);
}
PushUp(p);
}
inline int querymax(int nl,int nr,int l,int r,int p)
{
if(nl<=l && r<=nr)
{
return mx[p];
}
int mid=(l+r)>>1,res=-INF;
if(nl<=mid)
{
res=max(res,querymax(nl,nr,l,mid,ls(p)));
}
if(nr>mid)
{
res=max(res,querymax(nl,nr,mid+1,r,rs(p)));
}
return res;
}
inline int query(int nl,int nr,int l,int r,int p)
{
if(nl<=l && r<=nr)
{
return ans[p];
}
int mid=(l+r)>>1,res=0;
if(nl<=mid)
{
res+=query(nl,nr,l,mid,ls(p));
}
if(nr>mid)
{
res+=query(nl,nr,mid+1,r,rs(p));
}
return res;
}
inline void dfs1(int now,int fath,int depth)
{
fa[now]=fath;
size[now]=1;
dep[now]=depth;
int maxson=-1;
for(register int i=head[now];i;i=node[i].nxt)
{
int v=node[i].v;
if(v!=fath)
{
dfs1(v,now,depth+1);
size[now]+=size[v];
if(size[v]>maxson)
{
maxson=size[v];
son[now]=v;
}
}
}
}
inline void dfs2(int now,int topf)
{
id[now]=++tot;
top[now]=topf;
wt[tot]=a[now];
if(son[now]!=0)//非叶节点
{
dfs2(son[now],topf);//遍历重儿子
for(register int i=head[now];i;i=node[i].nxt)
{
int v=node[i].v;
if(v!=fa[now] && v!=son[now])
{
dfs2(v,v);//轻儿子
}
}
}
}
inline int getmax(int x,int y)
{
int res=-INF;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
{
swap(x,y);
}
res=max(res,querymax(id[top[x]],id[x],1,n,1));
x=fa[top[x]];
}
if(dep[x]>dep[y])
{
swap(x,y);
}
res=max(res,querymax(id[x],id[y],1,n,1));
return res;
}
inline int getsum(int x,int y)
{
int res=0,ans=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]])
{
swap(x,y);
}
res=query(id[top[x]],id[x],1,n,1);
ans+=res;
x=fa[top[x]];
}
if(dep[x]>dep[y])
{
swap(x,y);
}
res=query(id[x],id[y],1,n,1);
ans+=res;
return ans;
}
int main(void)
{
scanf("%d",&n);
for(register int i=1;i<=n-1;i++)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(register int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
int q;
scanf("%d",&q);
dfs1(1,0,1);
dfs2(1,1);
Build(1,1,n);
while(q--)
{
char opt[15];
int x,y;
cin>>opt;
scanf("%d%d",&x,&y);
if(opt[1]=='H')
{
Updata(x,x,1,n,1,y);
}
else if(opt[1]=='M')
{
printf("%d\n",getmax(x,y));
}
else
{
printf("%d\n",getsum(x,y));
}
}
return 0;
}