#include<bits/stdc++.h>
#define int long long
#define re register
#define in inline
#define dou long double
#define max(a,b) ((a)>(b)?a:b)
#define min(a,b) ((a)<(b)?a:b)
#define ls x<<1
#define rs x<<1|1
using namespace std;
const int N=2e6+10;
const int M=2e6+10;
const int INF=0x3f3f3f3f3f;
const int mod=988244353;
const dou eps=1e-5;
in int read(){
re int x=0,f=0;re char c=getchar();
while(!isdigit(c)) f|=(c=='-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+c-'0',c=getchar();
return f?-x:x;
}
in void write(re int x){
if(x<0) putchar('-'),x=-x;
if(x>9) write(x/10);
putchar(x%10+'0');
}
struct edge{
int u ,v;
int nx;
}e[M<<2];
int tot,head[N];
in void add(int u,int v){
e[++tot].u=u;
e[tot].v=v;
e[tot].nx=head[u];
head[u]=tot;
}
int a[N],w[N],idx,id[N],dep[N],top[N],f[N],siz[N],son[N];
struct tree{
int l,r;
int val,mx,sum;
}t[N<<2];
void pushup(int x){
t[x].sum=t[ls].sum+t[rs].sum;
t[x].mx=max(t[ls].mx,t[rs].mx);
}
void build(int x,int l,int r){
t[x].l=l;t[x].r=r;
if(l==r) {
t[x].sum=t[x].mx=t[x].val=a[l];
return ;
}
int mid=l+r>>1;
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
pushup(x);
}
void change(int x,int l,int v){
if(t[x].l==t[x].r){
t[x].val=t[x].sum=t[x].mx=v;
return ;
}
int mid=t[x].l+t[x].r>>1;
if(mid>=l)change(ls,l,v);
if(mid<l) change(rs,l,v);
pushup(x);
}
int ans;
void qmax(int x,int l,int r){
if(l<=t[x].l&&t[x].r<=r){
ans=max(ans,t[x].mx);
return ;
}
int mid=t[x].l+t[x].r>>1;
if(mid>=l) qmax(ls,l,r);
if(mid<r) qmax(rs,l,r);
}
void qsum(int x,int l,int r){
if(l<=t[x].l&&t[x].r<=r){
ans+=t[x].sum;
return ;
}
int mid=t[x].l+t[x].r>>1;
if(mid>=l) qsum(ls,l,r);
if(mid<r) qsum(rs,l,r);
}
void dfs1(int u,int fa,int deep){
dep[u]=deep;
f[u]=fa;
siz[u]=1;
int maxsiz=-1;
for(int i=head[u];i;i=e[i].nx){
int v=e[i].v;
if(v!=fa){
dfs1(v,u,deep+1);
siz[u]+=siz[v];
if(siz[v]>maxsiz){
son[u]=v;
maxsiz=siz[v];
}
}
}
}
void dfs2(int u,int topf){
idx++;
id[u]=idx;
top[u]=topf;
a[id[u]]=w[u];
if(!son[u]) return ;//这句是你忘的,,好好记住
dfs2(son[u],topf);
for(int i=head[u];i;i=e[i].nx){
int v=e[i].v;
if(v==son[u]||v==f[u]) continue;
dfs2(v,v);
}
}
int query(int x,int y){
ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<top[top[y]]) swap(x,y);
qsum(1,id[top[x]],id[x]);
x=f[top[x]];
//这里你没有写fa是因为你没有理解
//他已经计算过链子顶部了,你要跳出这个链子
}
//上下深度判断是不一样的,你失误了这里
if(dep[x]>dep[y]) swap(x,y);
qsum(1,id[x],id[y]);
return ans;
}
int querymax(int x,int y){
ans=-10000000;
//还有这,,,有负数的
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
qmax(1,id[top[x]],id[x]);
x=f[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
qmax(1,id[x],id[y]);
return ans;
}
int n,q;
signed main(){
n=read();
for(int i=1;i<n;i++){
int u,v;
u=read();v=read();
add(u,v);add(v,u);
}
for(int i=1;i<=n;i++){
w[i]=read();
}
dfs1(1,0,1);dfs2(1,1);
build(1,1,n);
q=read();
while(q--){
string s;int x,y;
cin>>s; x=read();y=read();
if(s[1]=='M'){
cout<<querymax(x,y)<<endl;
}
if(s[1]=='S'){
cout<<query(x,y)<<endl;
}
if(s[1]=='H'){
change(1,id[x],y);
//你在这里也理解错了是id[x],不是t[id[x]].l
//你TM连线段树单点修改都不会
}
}
return 0;
}
别人都20 30,我80,
我把讨论全看了,为什么我还是找不到问题,
1,3WA了,好离谱