一棵树上有 n个节点,编号分别为 1 到 n,每个节点都有一个权值 W。
我们将以下面的形式来要求你对这棵树完成一些操作:
I. CHANGE u t
: 把结点 u的权值改为 t。
II. QMAX u v
: 询问从点 u到点 v 的路径上的节点的最大权值。
III. QSUM u v
: 询问从点 u 到点 v 的路径上的节点的权值和。
#include <bits/stdc++.h> using namespace std ; const int N=5e5+4,M=N*2; #define inf 1e9 int n,nxt[M],hd[N],all,go[M],w[M]; int dep[N],sz[N],fa[N],son[N]; int dfn[N],id[N],pool,top[N]; void add_(int x,int y){ go[++all]=y; nxt[all]=hd[x],hd[x]=all; } #define k1 k<<1 #define k2 k<<1|1 int a[N]; struct Tree{ int sum,mx; int l,r; }tr[N<<2]; void up(int k){ tr[k].sum=tr[k1].sum+tr[k2].sum; tr[k].mx=max(tr[k1].mx,tr[k2].mx); } void add(int k,int x,int v){ if(tr[k].l==tr[k].r){ tr[k].sum=v; tr[k].mx=v; return; } int md=(tr[k].l+tr[k].r)/2; if(x<=md) add(k1,x,v); else add(k2,x,v); up(k); } int qmax(int k,int x,int y){ int t= -inf; if(x<=tr[k].l&&y>=tr[k].r) return tr[k].mx; int md=(tr[k].l+tr[k].r)/2; if(x<=md) t=max(t,qmax(k1,x,y)); if(y>md) t=max(t,qmax(k2,x,y)); return t; } int qsum(int k,int x,int y){ int t=0; if(x<=tr[k].l&&y>=tr[k].r) return tr[k].sum; int md=(tr[k].l+tr[k].r)/2; if(x<=md) t+=qsum(k1,x,y); if(y>md) t+=qsum(k2,x,y); return t; } void build(int k,int l,int r){ tr[k].l=l,tr[k].r=r; tr[k].sum=0; tr[k].mx= -inf; if(l==r){ tr[k].sum=tr[k].mx=a[id[l]]; return; } int md=(l+r)/2; build(k1,l,md),build(k2,md+1,r); up(k); } void dfs1(int x,int par){ fa[x]=par; sz[x]=1; dep[x]=dep[par]+1; son[x]=0; for(int i=hd[x];i;i=nxt[i]){ int y=go[i]; if(par==y) continue; dfs1(y,x); sz[x]+=sz[y]; if(sz[y]>sz[son[x]]) son[x]=y; } } void dfs2(int x,int topf){ dfn[x]=++pool; id[pool]=x; top[x]=topf; if(!son[x]) return ; dfs2(son[x],topf); for(int i=hd[x];i;i=nxt[i]){ int y=go[i]; if(y==fa[x]||y==son[x]) continue; dfs2(y,y); } } void upNode(int x,int v){ add(1,dfn[x],v); } int R_qMax(int x,int y){ int res=-inf; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); res=max(res, qmax(1,dfn[top[x]],dfn[x])); x=fa[top[x]]; } if(dep[x]>dep[y]) swap(x,y); res=max(res, qmax(1,dfn[x],dfn[y])) ; // return res; } int R_qSum(int x,int y){ int res=0; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]]) swap(x,y); res+=qsum(1,dfn[top[x]],dfn[x]); x=fa[top[x]]; } if(dep[x]>dep[y]) swap(x,y); res+=qsum(1,dfn[x],dfn[y]) ; return res; } signed main(){ cin>>n; int i,x,y,tes; string op; for(i=1;i<n;i++)cin>>x>>y,add_(x,y),add_(y,x); for(i=1;i<=n;i++) cin>>a[i]; dfs1(1,0); dfs2(1,1);build(1,1,n) ; cin>>tes; while(tes--){ cin>>op>>x>>y; if(op=="QMAX") cout<<R_qMax(x,y)<<endl; else if(op=="CHANGE") upNode(x,y); else if(op=="QSUM") cout<<R_qSum(x,y)<<endl; } }
标签:return,int,res,top,tr,son,P2590,ZJOI2008,统计 From: https://www.cnblogs.com/towboa/p/17204830.html