无脑码代码....
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')f=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0')
{
x=x*10+ch-'0';
ch=getchar();
}
return x*f;
}
void put(int x){
if(x==0){
putchar('0');
putchar('\n');
return;
}
if(x<0){
putchar('-');
x=-x;
}
int num=0;char ch[16];
while(x) ch[++num]=x%10+'0',x/=10;
while(num) putchar(ch[num--]);
putchar('\n');
}
struct one
{
int y,next;
};
one e[60100];
struct ppp
{
int l,r,val,maxn;
};
ppp tree[130000];
char s[20];
int maxn=1000000000,maxn2=-1000000000,a[30010],w[30010],n,m,fa[30010],d[30010],sizer[30010],top[30010],lin[30010],len=0,din[30010],dout[30010],wson[30010],cnt=0;
/*void dfs1(int x,int f)
{
int y;
fa[x]=f;
wson[x]=0;//the heaviest son
sizer[x]=1;
for (int i=lin[x];i;i=e[i].next)
if (e[i].y!=f)
{
y=e[i].y;
d[y]=d[x]+1;
dfs1(y,x);
sizer[x]+=sizer[y];
if (sizer[wson[x]]<sizer[y])
wson[x]=y;
}
} */
void dfs1(int p,int f)
{
int y;
fa[p]=f;
wson[p]=0;
sizer[p]=1;
for(int i=lin[p];i;i=e[i].next)
{
int maxnx2=0,ww=0;
if(e[i].y!=f)
{
y=e[i].y;
d[y]=d[p]+1;
dfs1(y,p);
sizer[p]+=sizer[y];
/*if(sizer[y]>maxnx2)
{
maxnx2=sizer[y];
wson[p]=y;
}*/
if (sizer[wson[p]]<sizer[y])
wson[p]=y;
}
}
}
void dfs2(int p)
{
din[p]=++cnt;
w[cnt]=a[p];
if(!top[p])top[p]=p;
if(wson[p])
{
top[wson[p]]=top[p];
dfs2(wson[p]);
}
for(int i=lin[p];i;i=e[i].next)
{
if(fa[p]==e[i].y||e[i].y==wson[p])continue;
dfs2(e[i].y);
}
//dout[p]=cnt;
}
void insert(int x,int y)
{
e[++len].next=lin[x];
lin[x]=len;
e[len].y=y;
}
void maketree(int l,int r,int id)
{
tree[id].l=l;tree[id].r=r;
if(l>=r)
{
tree[id].maxn=w[l];
tree[id].val=w[l];
return;
}
int mid=(l+r)>>1;
maketree(l,mid,id<<1);
maketree(mid+1,r,id<<1|1);
tree[id].maxn=max(tree[id<<1].maxn,tree[id<<1|1].maxn);
tree[id].val=tree[id<<1].val+tree[id<<1|1].val;
}
/*void chag(int l,int val,int id)
{
if(l<tree[id].l||l>tree[id].r)return;
if(tree[id].l==tree[id].r){tree[id].maxn=val;tree[id].val=val;return;}
int mid=(tree[id].l+tree[id].r)>>1;
if(l<=mid)chag(l,val,id<<1);
else chag(l,val,id<<1|1);
tree[id].maxn=max(tree[id<<1].maxn,tree[id<<1|1].maxn);
tree[id].val=tree[id<<1].val+tree[id<<1|1].val;
}*/
void updata(int p)
{
tree[p].val=tree[p<<1].val+tree[p<<1|1].val;
tree[p].maxn=max(tree[p<<1].maxn,tree[p<<1|1].maxn);
}
void chag(int x,int y,int p)
{
if (tree[p].l==x && tree[p].r==x)
{
tree[p].val=tree[p].maxn=y;
return ;
}
int mid=(tree[p].l+tree[p].r) >> 1;
if (x<=mid) chag(x, y,p<<1);
if (x>mid) chag(x, y,p<<1|1);
updata(p);
}
/*int putit2(int l,int r,int id)
{
if(tree[id].r<l||r<tree[id].l)return -maxn;
if(tree[id].r<=r&&tree[id].l>=l)return tree[id].maxn;
int a1=putit2(l,r,id<<1);
int a2=putit2(l,r,id<<1|1);
a1=max(a1,a2);
return a1;
}*/
int putit2(int l,int r,int p)
{
if (tree[p].l==l && tree[p].r==r)
return tree[p].maxn;
int mid=(tree[p].l+tree[p].r) >> 1;
if (r<=mid) return putit2(l, r,p<<1);
if (l>mid) return putit2(l, r,p<<1|1);
if (l<=mid && r>mid)
{
int s1=putit2(l, mid,p<<1);
int s2=putit2(mid+1, r,p<<1|1);
return max(s1,s2);
}
}
void putit1(int x,int y)
{
int ans=-maxn;
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]])
{
ans=max(ans,putit2(din[top[y]],din[y],1));
y=fa[top[y]];
}
else
{
ans=max(ans,putit2(din[top[x]],din[x],1));
x=fa[top[x]];
}
}
if(d[x]<d[y])ans=max(ans,putit2(din[x],din[y],1));
else ans=max(ans,putit2(din[y],din[x],1));
put(ans);
}
/*int putsum2(int l,int r,int id)
{
if(tree[id].r<l||r<tree[id].l)return 0;
if(tree[id].r<=r&&tree[id].l>=l)return tree[id].val;
int mid=(tree[id].r+tree[id].l)>>1;
if(l>=mid)
int a1=putsum2(l,r,id<<1);
int a2=putsum2(l,r,id<<1|1);
return a1+a2;
}*/
int putsum2(int l,int r,int p)
{
if (tree[p].l==l && tree[p].r==r)
return tree[p].val;
int mid=(tree[p].l+tree[p].r) >> 1;
if (r<=mid) return putsum2(l, r,p<<1);
if (l>mid) return putsum2( l, r,p<<1|1);
if (l<=mid && r>mid)
{
int s1=putsum2(l, mid,p<<1);
int s2=putsum2(mid+1, r,p<<1|1);
return s1+s2;
}
}
void putsum1(int x,int y)
{
int ans=0;
while(top[x]!=top[y])
{
if(d[top[x]]<d[top[y]])
{
ans+=putsum2(din[top[y]],din[y],1);
y=fa[top[y]];
}
else
{
ans+=putsum2(din[top[x]],din[x],1);
x=fa[top[x]];
}
}
if(d[x]==d[y])
{
ans+=putsum2(din[x],din[x],1);
}
else if(d[x]<d[y])
{
ans+=putsum2(din[x],din[y],1);
}
else
{
ans+=putsum2(din[y],din[x],1);
}
//printf("%d\n",ans);
put(ans);
}
int main()
{
//freopen("xf.in","r",stdin);
//freopen("xf.out","w",stdout);
n=read();
int aa,bb;
for(int i=1;i<n;i++)
{
aa=read();bb=read();
insert(aa,bb);insert(bb,aa);
}
for(int i=1;i<=n;i++)a[i]=read();
d[1]=1;
//dfs1(1);dfs2(1);
dfs1(1,0);
dfs2(1);
maketree(1,n,1);
scanf("%d",&m);
int x,y;
for(int i=1;i<=m;i++)
{
scanf("%s",s);
x=read();y=read();
if(s[0]=='C')chag(din[x],y,1);
else if(s[1]=='M')putit1(x,y);
else putsum1(x,y);
}
return 0;
}