题目:I. CHANGE u t : 把结点u的权值改为t
II. QMAX u v: 询问从点u到点v的路径上的节点的最大权值
III. QSUM u v: 询问从点u到点v的路径上的节点的权值和
注意:从点u到点v的路径上的节点包括u和v本身
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=30010;
int to[maxn*2],Next[maxn*2],Begin[maxn],e;
void add(int x,int y){
to[++e]=y;
Next[e]=Begin[x];
Begin[x]=e;
}
int n,cnt;
int sz[maxn],son[maxn],top[maxn],fa[maxn];
int dep[maxn];
int id[maxn],tmp[maxn];
int val[maxn*4],Max[maxn*4];
int sumans,maxans;
void maintain(int o,int l,int r){
Max[o]=max(Max[o<<1],Max[o<<1|1]);
val[o]=val[o<<1]+val[o<<1|1];
}
void update(int o,int l,int r,int x,int y){
if(l==r){
val[o]=Max[o]=y;
return;
}
int mid=(l+r)>>1;
if(x<=mid) update(o<<1,l,mid,x,y);
else update(o<<1|1,mid+1,r,x,y);
maintain(o,l,r);
}
void query(int o,int l,int r,int x,int y){
if(x==l && y==r){
maxans=max(maxans,Max[o]);
sumans+=val[o];
return;
}
int mid=(l+r)>>1;
if(y<=mid) query(o<<1,l,mid,x,y);
else if(x>mid) query(o<<1|1,mid+1,r,x,y);
else{
query(o<<1,l,mid,x,mid);
query(o<<1|1,mid+1,r,mid+1,y);
}
}
void dfs1(int u){
sz[u]=1;
for(int i=Begin[u];i;i=Next[i]){
int v=to[i];
if(v==fa[u]) continue;
dep[v]=dep[u]+1;
fa[v]=u;
dfs1(v);
sz[u]+=sz[v];
if(sz[v]>sz[son[u]]) son[u]=v;
}
}
void dfs2(int u){
id[u]=++cnt;
update(1,1,n,id[u],tmp[u]);
if(!son[u]) return;
top[son[u]]=top[u];
dfs2(son[u]);
for(int i=Begin[u];i;i=Next[i]){
int v=to[i];
if(id[v]) continue;
top[v]=v;
dfs2(v);
}
}
void solve(int u,int v){
maxans=-0x3f3f3f3f;
sumans=0;
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]]) swap(u,v);
query(1,1,n,id[top[u]],id[u]);
u=fa[top[u]];
}
if(dep[u]<dep[v]) swap(u,v);
query(1,1,n,id[v],id[u]);
}
int main(){
scanf("%d",&n);
for(int i=1;i<n;i++){
int a,b;
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
for(int i=1;i<=n;i++) scanf("%d",&tmp[i]);
dep[1]=1;top[1]=1;
dfs1(1);
dfs2(1);
int q;
scanf("%d",&q);
int ans;
while(q--){
char s[20];
int u,v;
scanf("%s%d%d",s,&u,&v);
if(s[1]=='H'){
update(1,1,n,id[u],v);
}else{
solve(u,v);
if(s[1]=='M') ans=maxans;
else ans=sumans;
printf("%d\n",ans);
}
}
return 0;
}
^_^