具体实现方面的话,上文所提的重儿子,顶端,深度等等都要提前预处理出来,后面就是用线段树维护了。
----------------------------------------------------------------------------------------------------
#include<cstdio>
#include<algorithm>
#define MAXN 30005
#define INF 1<<30
using namespace std;
 
int l[MAXN],r[MAXN];
struct node
{
        int sum,max;
};
node tree[MAXN*4];     
 
struct Edge
{
        int v,next;
};
Edge edge[MAXN*2];
int head[MAXN],now,val[MAXN],link[MAXN],dep[MAXN],fa[MAXN],sonTree[MAXN],heavySon[MAXN],tot,top[MAXN],num[MAXN];     
int n,u,v,q;
 
void addEdge(int u,int v)
{
        now++;
        edge[now].v=v;
        edge[now].next=head[u];
        head[u]=now;
}
void buildTree(int now,int l,int r)
{
       if (l==r) 
       {
                tree[now].max=val[link[l]];
                tree[now].sum=val[link[l]];
                return;
       }
       int mid=(l+r)/2;
       buildTree(now*2,l,mid);
       buildTree(now*2+1,mid+1,r);
       tree[now].max=max(tree[now*2].max,tree[now*2+1].max);
       tree[now].sum=tree[now*2].sum+tree[now*2+1].sum;
}
 
void DFS1(int now,int nowFa,int nowDep)
{
       dep[now]=nowDep; fa[now]=nowFa; sonTree[now]=1;
       for (int x=head[now];x!=0;x=edge[x].next)
       {
              if (edge[x].v==nowFa) continue;
              DFS1(edge[x].v,now,nowDep+1);
              sonTree[now]+=sonTree[edge[x].v];
              if (heavySon[now]==0 || sonTree[edge[x].v]>sonTree[heavySon[now]]) heavySon[now]=edge[x].v;
       }
}
 
void DFS2(int now,int nowTop)
{
       tot++;
       top[now]=nowTop; num[now]=tot; link[tot]=now;
       if (heavySon[now]==0) return;
       DFS2(heavySon[now],nowTop);
       for (int x=head[now];x!=0;x=edge[x].next)
              if (edge[x].v!=heavySon[now] && edge[x].v!=fa[now]) DFS2(edge[x].v,edge[x].v);
}
 
void init()
{
       scanf("%d",&n);
       for (int i=1;i<=n-1;i++) 
       {
              scanf("%d %d",&u,&v);
              addEdge(u,v); addEdge(v,u);
       }
       for (int i=1;i<=n;i++) scanf("%d",&val[i]);
       DFS1(1,0,1); DFS2(1,1);
       buildTree(1,1,n);
}
 
void update1(int now,int l,int r,int loc,int delta)
{
       if (l==r)
       {
              tree[now].sum+=delta;
              tree[now].max+=delta;
              return;
       }
       int mid=(l+r)/2;
       if (loc<=mid) update1(now*2,l,mid,loc,delta);
       else update1(now*2+1,mid+1,r,loc,delta);
       tree[now].max=max(tree[now*2].max,tree[now*2+1].max);
       tree[now].sum=tree[now*2].sum+tree[now*2+1].sum;
}
 
int query1(int now,int l,int r,int ql,int qr)
{
       int ans=0;
       if (ql<=l && r<=qr) return tree[now].sum;
       int mid=(l+r)/2;
       if (ql<=mid) ans+=query1(now*2,l,mid,ql,qr);
       if (qr>mid) ans+=query1(now*2+1,mid+1,r,ql,qr);
       return ans;
}
 
int query2(int now,int l,int r,int ql,int qr)
{
       int ans=-INF;
       if (ql<=l && r<=qr) return tree[now].max;
       int mid=(l+r)/2;
       if (ql<=mid) ans=max(ans,query2(now*2,l,mid,ql,qr));
       if (qr>mid) ans=max(ans,query2(now*2+1,mid+1,r,ql,qr));
       return ans;
}
 
int getMax(int l,int r)
{
       int f1=top[l],f2=top[r],ans=-INF,nowAns;
       while (f1!=f2)
       {
              if (dep[f1]<dep[f2]) swap(f1,f2),swap(l,r);
             ans=max(ans,query2(1,1,n,num[f1],num[l]));
             l=fa[f1]; f1=top[l];
       }
       if (dep[l]>dep[r]) nowAns=query2(1,1,n,num[r],num[l]);
       else nowAns=query2(1,1,n,num[l],num[r]);
       ans=max(ans,nowAns);
       return ans;
}
 
int getSum(int l,int r)
{
       int f1=top[l],f2=top[r],ans=0,nowAns;
       while (f1!=f2)
       {
              if (dep[f1]<dep[f2]) swap(f1,f2),swap(l,r);
              ans+=query1(1,1,n,num[f1],num[l]);
              l=fa[f1]; f1=top[l];
       }
      if (dep[l]>dep[r]) nowAns=query1(1,1,n,num[r],num[l]);
      else nowAns=query1(1,1,n,num[l],num[r]);
      ans+=nowAns;
      return ans;
}
 
int main()
{
       char s[7];
       init();
       scanf("%d",&q);
       for (int i=1;i<=q;i++) 
       {
              scanf("%s %d %d",s,&u,&v);
              if (s[0]==‘C‘) { update1(1,1,n,num[u],v-val[u]); val[u]=v; }
              else if (s[1]==‘M‘) printf("%d\n",getMax(u,v));
              else printf("%d\n",getSum(u,v)); 
       }
       return 0;
}
----------------------------------------------------------------------------------------------------