![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; const int MX=30011; struct Edge{int to,nxt;}e[2*MX]; struct node{int mx;long long sum;}t[4*MX]; int n,Index,fir[MX],fa[MX],dfn[MX],dep[MX],siz[MX],son[MX],Top[MX],w[MX],bel[MX],dfs_cnt; inline void ins(int u,int v){e[++Index]=(Edge){v,fir[u]},fir[u]=Index;} void dfs1(int x){ siz[x]++,dep[x]=dep[fa[x]]+1; for(int i=fir[x];i;i=e[i].nxt)if(e[i].to!=fa[x]){ fa[e[i].to]=x; dfs1(e[i].to); siz[x]+=siz[e[i].to]; if(siz[e[i].to]>siz[son[x]])son[x]=e[i].to; } } void dfs2(int x){ Top[x]=(son[fa[x]]==x)?Top[fa[x]]:x; dfn[x]=++dfs_cnt,bel[dfs_cnt]=x; if(!son[x])return; dfs2(son[x]); for(int i=fir[x];i;i=e[i].nxt)if(e[i].to!=fa[x]&&e[i].to!=son[x]){ dfs2(e[i].to); } } #define ls(x) (x<<1) #define rs(x) (x<<1|1) inline void push_up(int o){ t[o].mx=max(t[ls(o)].mx,t[rs(o)].mx); t[o].sum=t[ls(o)].sum+t[rs(o)].sum; } void build(int L,int R,int o){ if(L==R){t[o].sum=t[o].mx=w[bel[L]];return;} int mid=L+R>>1; build(L,mid,ls(o)),build(mid+1,R,rs(o)); push_up(o); } void updata(int L,int R,int o,int x,int v){ if(L==R){t[o].mx=t[o].sum=v;return;} int mid=L+R>>1; if(x<=mid)updata(L,mid,ls(o),x,v); else updata(mid+1,R,rs(o),x,v); push_up(o); } long long query(int L,int R,int o,int l,int r,int f){ if(L==l&&R==r)return (~f)?t[o].sum:t[o].mx; int mid=L+R>>1; if(r<=mid)return query(L,mid,ls(o),l,r,f); else if(l>mid) return query(mid+1,R,rs(o),l,r,f); else { if(~f)return query(L,mid,ls(o),l,mid,f)+query(mid+1,R,rs(o),mid+1,r,f); else return max(query(L,mid,ls(o),l,mid,f),query(mid+1,R,rs(o),mid+1,r,f)); } } const int inf=0x7fffffff; long long Query(int u,int v,int f){ long long ret=(~f)?0:-inf; while(Top[u]!=Top[v]){ if(dep[Top[u]]<dep[Top[v]])swap(u,v); if(~f)ret+=query(1,n,1,dfn[Top[u]],dfn[u],f); else ret=max(ret,query(1,n,1,dfn[Top[u]],dfn[u],f)); u = fa[Top[u]]; } if(dep[u]<dep[v])swap(u,v); if(~f)ret+=query(1,n,1,dfn[v],dfn[u],f); else ret=max(ret,query(1,n,1,dfn[v],dfn[u],f)); return ret; } char op[20]; int main(){ #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif scanf("%d",&n); for(int i=1;i<n;i++){ int u,v;scanf("%d%d",&u,&v); ins(u,v),ins(v,u); } for(int i=1;i<=n;i++)scanf("%d",w+i); dfs1(1),dfs2(1),build(1,n,1); int q,u,v;scanf("%d",&q); while(q--){ scanf("%s%d%d",op,&u,&v); if(*op=='C')updata(1,n,1,dfn[u],v); else printf("%lld ",op[1]=='S'?Query(u,v,1):Query(u,v,-1)); } }