模板
注意事项:
-
需要的数组:1.建图(ver,nex,head). 2,维护链的数据结构:线段树/树状数组. 3.树剖:dfn,wson,top,size,deep
- dfn[1]=fa[1]=1;
- gai(dfn[x])
- dfs1记录字数大小size/深度d/父节点fa/重儿子wson
- dfs1记录dfn,pre,链顶top
#include<iostream> #include<stdio.h> using namespace std; int g,q,h,i,m,n,j,k,a[100001],nex[100001],head[100001],ver[100001],cnt; int wson[100005],top[100005],dfn[100001],d[100001],fa[100001],size[100001]; int pre[100005],sum[400010],smm[400011]; char c[10001]; void add(int x,int y) { cnt+=1; ver[cnt]=y; nex[cnt]=head[x]; head[x]=cnt; } void update(int now) { sum[now]=sum[now*2]+sum[now*2+1]; smm[now]=max(smm[now*2],smm[now*2+1]); } void built(int now,int l,int r) { if(l==r) sum[now]=smm[now]=a[pre[l]]; else { int mid=(l+r)/2; built(now*2,l,mid); built(now*2+1,mid+1,r); update(now); } } void dfs1(int x,int y) { size[x]=1; for(int i=head[x];i;i=nex[i]) { int t=ver[i]; if(t==y) continue; fa[t]=x; d[t]=d[x]+1; dfs1(t,x); if(size[t]>size[wson[x]]) wson[x]=t; size[x]+=size[t]; } } void dfs2(int x,int y) { cnt+=1; dfn[x]=cnt; pre[cnt]=x; top[x]=y; if(wson[x]) dfs2(wson[x],y); for(int i=head[x];i;i=nex[i]) { int t=ver[i]; if(t==fa[x] || t==wson[x]) continue; dfs2(t,t); } } int qsum(int now,int l,int r,int ll,int rr) { if((l>=ll)&&(r<=rr)) return sum[now]; int mid=(l+r)/2,ans=0; if(ll<=mid) ans+=qsum(now*2,l,mid,ll,rr); if(rr>mid) ans+=qsum(now*2+1,mid+1,r,ll,rr); return ans; } int qmax(int now,int l,int r,int ll,int rr) { if((l>=ll)&&(r<=rr)) return smm[now]; int mid=(l+r)/2,ans=-0x7ffffff; if(ll<=mid) ans=max(ans,qmax(now*2,l,mid,ll,rr)); if(rr>mid) ans=max(ans,qmax(now*2+1,mid+1,r,ll,rr)); return ans; } void gai(int now,int l,int r,int w,int z) { if(l==r) sum[now]=smm[now]=z; else { int mid=(l+r)/2,ans=0; if(mid>=w) gai(now*2,l,mid,w,z); else gai(now*2+1,mid+1,r,w,z); update(now); } } int cham(int x,int y) { int ans=-0x7fffffff; while(top[x]!=top[y]) { if(d[top[x]]<d[top[y]]) swap(x,y); ans=max(qmax(1,1,n,dfn[top[x]],dfn[x]),ans); x=fa[top[x]]; } if(d[x]<d[y]) swap(x,y); ans=max(ans,qmax(1,1,n,dfn[y],dfn[x])); return ans; } int chas(int x,int y) { int ans=0; while(top[x]!=top[y]) { if(d[top[x]]<d[top[y]]) swap(x,y); ans+=qsum(1,1,n,dfn[top[x]],dfn[x]); x=fa[top[x]]; } if(d[x]<d[y]) swap(x,y); ans+=qsum(1,1,n,dfn[y],dfn[x]); return ans; } int main() { scanf("%d",&n); for(i=1;i<n;i++) { scanf("%d%d",&g,&h); add(g,h); add(h,g); } for(i=1;i<=n;i++) scanf("%d",&a[i]); scanf("%d",&q); d[1]=fa[1]=1; cnt=0; dfs1(1,0); dfs2(1,1); built(1,1,n); for(i=1;i<=q;i++) { scanf("%s%d%d",c,&g,&h); if(c[1]=='H') gai(1,1,n,dfn[g],h); if(c[1]=='M') printf("%d\n",cham(g,h)); if(c[1]=='S') printf("%d\n",chas(g,h)); } }