/*
题目描述 Description
一棵树上有n个节点,编号分别为1到n,每个节点都有一个权值w。
我们将以下面的形式来要求你对这棵树完成一些操作:
- I. CHANGE u t : 把结点u的权值改为t
- II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值
- III. QSUM u v: 询问从点u到点v的路径上的节点的权值和
注意:从点u到点v的路径上的节点包括u和v本身
输入描述 Input Description
输入文件的第一行为一个整数n,表示节点的个数。
接下来n – 1行,每行2个整数a和b,表示节点a和节点b之间有一条边相连。
接下来n行,每行一个整数,第i行的整数wi表示节点i的权值。
接下来1行,为一个整数q,表示操作的总数。
接下来q行,每行一个操作,以“CHANGE u t”或者“QMAX u v”或者“QSUM u v”的形式给出。
输出描述 Output Description
对于每个“QMAX”或者“QSUM”的操作,每行输出一个整数表示要求输出的结果。*/
#include<cstdio> #include<iostream> #include<cmath> using namespace std; int head[30008],next[60008],v[60008],n,w[30008],shu[30008],size[30008],fa[30008]; int deep[30008],len,head1[30008],next1[60008],v1[60008],cnt,maxx[30008],sum[30008]; void dfs(int a1) { for(int i=head[a1];i;i=next[i]) if(v[i]!=fa[a1]) { fa[v[i]]=a1; deep[v[i]]=deep[a1]+1; if(size[shu[a1]]<len) { size[shu[a1]]++; shu[v[i]]=shu[a1]; cnt++; next1[cnt]=head1[a1]; head1[a1]=cnt; v1[cnt]=v[i]; } dfs(v[i]); } return; } void dfs1(int a1,int a2,int a3) { a2+=w[a1]; sum[a1]=a2; a3=max(a3,w[a1]); maxx[a1]=a3; for(int i=head1[a1];i;i=next1[i]) dfs1(v1[i],a2,a3); return; } void gai(int a1,int a2) { w[a1]=a2; if(shu[a1]==a1) dfs1(a1,0,-1000000); else dfs1(a1,sum[fa[a1]],maxx[fa[a1]]); return; } pair<int,int> he(int a1,int a2) { int s=0,ma=-1000000; for(;a1!=a2;) { if(deep[a1]<deep[a2]) swap(a1,a2); if(shu[a1]==shu[a2]) { s+=w[a1]; ma=max(w[a1],ma); a1=fa[a1]; } else { if(deep[shu[a1]]<deep[shu[a2]]) swap(a1,a2); s+=sum[a1]; ma=max(maxx[a1],ma); a1=fa[shu[a1]]; } } s+=w[a1]; ma=max(w[a1],ma); return pair<int,int>(s,ma); } int main() { scanf("%d",&n); len=sqrt(n); for(int i=1;i<n;i++) { int a1,a2; scanf("%d%d",&a1,&a2); next[i]=head[a1]; head[a1]=i; v[i]=a2; next[i+n]=head[a2]; head[a2]=i+n; v[i+n]=a1; } for(int i=1;i<=n;i++) { scanf("%d",&w[i]); shu[i]=i; size[i]=1; } dfs(1); for(int i=1;i<=n;i++) if(shu[i]==i) dfs1(i,0,-100000); int m; scanf("%d",&m); for(int i=0;i<m;i++) { char ch[10]; int a1,a2; scanf("%s%d%d",ch,&a1,&a2); if(ch[0]=='C') gai(a1,a2); else { pair<int,int>anss=he(a1,a2); if(ch[1]=='S') printf("%d ",anss.first); else printf("%d ",anss.second); } } return 0; }