开两个线段树,一个维护和,一个维护最大值。
#include<bits/stdc++.h> using namespace std; #define int long long const int maxn=300000+100; int n,q; int beg[maxn],nex[maxn],to[maxn],e; inline void add(int x,int y){ e++;nex[e]=beg[x]; beg[x]=e;to[e]=y; } int val[maxn]; int f[maxn],son[maxn],size[maxn],dep[maxn]; inline void dfs1(int x,int fa){ f[x]=fa; dep[x]=dep[fa]+1; size[x]=1; for(int i=beg[x];i;i=nex[i]){ int t=to[i]; if(t==fa)continue; dfs1(t,x); size[x]+=size[t]; if(size[t]>size[son[x]])son[x]=t; } } int id[maxn],num[maxn],top[maxn],cnt; inline void dfs2(int x,int topc){ id[x]=++cnt; num[cnt]=val[x]; top[x]=topc; if(!son[x])return; dfs2(son[x],topc); for(int i=beg[x];i;i=nex[i]){ int t=to[i]; if(t==f[x]||t==son[x])continue; dfs2(t,t); } } int tsum[maxn],tmax[maxn]; inline void build(int h,int l,int r){ if(l==r){ tsum[h]=tmax[h]=num[l]; return; } int mid=(l+r)>>1; build(h<<1,l,mid); build(h<<1|1,mid+1,r); tsum[h]=tsum[h<<1]+tsum[h<<1|1]; tmax[h]=max(tmax[h<<1],tmax[h<<1|1]); } inline void update(int h,int l,int r,int pos,int val1){ if(l==r){ tsum[h]=tmax[h]=val1; return; } int mid=(l+r)>>1; if(mid>=pos)update(h<<1,l,mid,pos,val1); else update(h<<1|1,mid+1,r,pos,val1); tsum[h]=tsum[h<<1]+tsum[h<<1|1]; tmax[h]=max(tmax[h<<1],tmax[h<<1|1]); } inline int querymax(int h,int l,int r,int x,int y){ if(l>y||r<x)return -1e15; if(l>=x&&r<=y)return tmax[h]; int mid=(l+r)>>1; return max(querymax(h<<1,l,mid,x,y),querymax(h<<1|1,mid+1,r,x,y)); } inline int Qmax(int x,int y){ int ans=-1e15; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); ans=max(ans,querymax(1,1,n,id[top[x]],id[x])); x=f[top[x]]; } if(dep[x]>dep[y])swap(x,y); ans=max(ans,querymax(1,1,n,id[x],id[y])); return ans; } inline int querysum(int h,int l,int r,int x,int y){ if(l>y||r<x)return 0; if(l>=x&&r<=y)return tsum[h]; int mid=(l+r)>>1; return querysum(h<<1,l,mid,x,y)+querysum(h<<1|1,mid+1,r,x,y); } inline int Qsum(int x,int y){ int ans=0; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); ans+=querysum(1,1,n,id[top[x]],id[x]); x=f[top[x]]; } if(dep[x]>dep[y])swap(x,y); ans+=querysum(1,1,n,id[x],id[y]); return ans; } signed main(){ //freopen("tree.in","r",stdin); cin>>n; int x,y; for(int i=1;i<n;i++){ scanf("%lld%lld",&x,&y); add(x,y);add(y,x); } for(int i=1;i<=n;i++) scanf("%lld",&val[i]); dfs1(1,0); dfs2(1,1); build(1,1,n); cin>>q; string opt; for(int i=1;i<=q;i++){ cin>>opt; if(opt=="CHANGE"){ scanf("%lld%lld",&x,&y); update(1,1,n,id[x],y); }else if(opt=="QMAX"){ scanf("%lld%lld",&x,&y); printf("%lld ",Qmax(x,y)); }else{ scanf("%lld%lld",&x,&y); printf("%lld ",Qsum(x,y)); } } return 0; }
深深地感到自己的弱小。