#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define maxn 300000
#define ls x<<1
#define rs x<<1|1
using namespace std;
int n,head[maxn],tot=0,v[maxn],top[maxn],son[maxn],fa[maxn],de[maxn],w[maxn],z,tree1[maxn],tree2[maxn],sz[maxn];
char s[20];
struct eg
{
int to;
int nxt;
}b[maxn];
void link(int x,int y)
{
b[++tot].nxt=head[x];
b[tot].to=y;
head[x]=tot;
}
void dfs1(int x,int f)
{
sz[x]=1,fa[x]=f;
for (int i=head[x];i!=-1;i=b[i].nxt)
{
int t=b[i].to;
if (t==f) continue;
de[t]=de[x]+1;
dfs1(t,x);
sz[x]+=sz[t];
if (son[x]==-1||sz[son[x]]<sz[t]) son[x]=t;
}
}
void dfs2(int x,int tp)
{
top[x]=tp,w[x]=++z;
if (son[x]!=-1) dfs2(son[x],tp);
else return ;
for (int i=head[x];i!=-1;i=b[i].nxt)
{
int t=b[i].to;
if (t!=fa[x]&&t!=son[x]) dfs2(t,t);
}
}
void build(int x,int l,int r)
{
tree2[x]=0,tree1[x]=-900000000;
if (l==r) return ;
int mid=(l+r)>>1;
build (ls,l,mid);
build (rs,mid+1,r);
}
void updata(int x,int l,int r,int d,int y)
{
if (l==r&&l==d)
{
tree1[x]=y;
tree2[x]=y;
return ;
}
int mid=(l+r)>>1;
if (d<=mid)updata(ls,l,mid,d,y);
else updata(rs,mid+1,r,d,y);
tree1[x]=max(tree1[ls],tree1[rs]);
tree2[x]=tree2[ls]+tree2[rs];
}
int qsum(int x,int l,int r,int ll,int rr)
{
if (ll==l&&r==rr) return tree2[x];
int mid=(l+r)>>1;
if (ll>mid) return qsum(rs,mid+1,r,ll,rr);
else if (rr<=mid) return qsum(ls,l,mid,ll,rr);
else return qsum(ls,l,mid,ll,mid)+qsum(rs,mid+1,r,mid+1,rr);
}
int qmax(int x,int l,int r,int ll,int rr)
{
if (ll==l&&r==rr) return tree1[x];
int mid=(l+r)>>1;
if (rr<=mid) return qmax(ls,l,mid,ll,rr);
else if (ll>mid) return qmax(rs,mid+1,r,ll,rr);
else return max(qmax(ls,l,mid,ll,mid),qmax(rs,mid+1,r,mid+1,rr));
}
int find(int x,int y,int flag)
{
if (flag==1)
{
int ans=-900000000;
int f1=top[x],f2=top[y];
while(f1!=f2)
{
if(de[f1]<de[f2]) swap(f1,f2),swap(x,y);
ans=max(ans,qmax(1,1,z,w[f1],w[x]));
x=fa[f1],f1=top[x];
}
if (de[x]>de[y]) swap(x,y);
return max(ans,qmax(1,1,z,w[x],w[y]));
}
if (flag==2)
{
int ans=0;
int f1=top[x],f2=top[y];
while (f1!=f2)
{
if(de[f1]<de[f2]) swap(f1,f2),swap(x,y);
ans+=qsum(1,1,z,w[f1],w[x]);
x=fa[f1],f1=top[x];
}
if (de[x]>de[y]) swap(x,y);
return ans+qsum(1,1,z,w[x],w[y]);
}
}
int main()
{
memset(head, -1, sizeof(head));
memset(son, -1, sizeof(son));
scanf ("%d",&n);
for (int i=1;i<n;++i)
{
int x,y;
scanf ("%d%d",&x,&y);
link(x,y);
link(y,x);
}
for (int i=1;i<=n;++i)
scanf ("%d",&v[i]);
de[1]=1;
dfs1(1,0);
dfs2(1,1);
build(1,1,z);
for (int i=1;i<=n;++i) updata(1,1,z,w[i],v[i]);
int q;
scanf("%d",&q);
for (int i=1;i<=q;++i)
{
scanf ("%s",s);
int x,y;
scanf ("%d%d",&x,&y);
if (s[0]=='C')
updata(1,1,z,w[x],y);
if (s[1]=='M')
printf("%d\n",find(x,y,1));
if (s[1]=='S')
printf("%d\n",find(x,y,2));
}
return 0;
}
嗯我知道打得很丑然而毕竟是第一个几乎全靠自己的树剖板子吧qaq
诶嘿嘿