[树链剖分]JZOJ 2677 树A
分析
树剖模板……
#include <iostream> #include <cstdio> #define lson (x<<1) #define rson ((x<<1)+1) using namespace std; const int N=3e4+10; struct Graph { int v,nx; }g[2*N]; int cnt,list[N]; int top[N],sz[N],seg[N],f[N],dep[N],son[N],w[N]; int t[4*N],scnt,rev[N],rt=1; int n,m; void Add(int u,int v) { g[++cnt]=(Graph){v,list[u]};list[u]=cnt; g[++cnt]=(Graph){u,list[v]};list[v]=cnt; } void DFS(int u,int fa) { dep[u]=dep[fa]+1;f[u]=fa;sz[u]=1; for (int i=list[u];i;i=g[i].nx) if (g[i].v!=fa) { DFS(g[i].v,u); sz[u]+=sz[g[i].v]; if (sz[g[i].v]>sz[son[u]]) son[u]=g[i].v; } } void DFS(int u) { int s=son[u]; if (s) { top[s]=top[u]; rev[seg[s]=++scnt]=s; DFS(s); } for (int i=list[u];i;i=g[i].nx) if (!top[g[i].v]) top[g[i].v]=g[i].v,rev[seg[g[i].v]=++scnt]=g[i].v,DFS(g[i].v); } void Update(int x) {t[x]=t[lson]+t[rson];} void Build(int x,int l,int r) { if (l==r) { t[x]=w[rev[l]]; return; } int mid=l+r>>1; Build(lson,l,mid);Build(rson,mid+1,r); Update(x); } void Change(int x,int l,int r,int k,int z) { if (k<l||r<k) return; if (l==r&&l==k) { t[x]=z; return; } int mid=l+r>>1; if (k<=mid) Change(lson,l,mid,k,z); else Change(rson,mid+1,r,k,z); Update(x); } int Query(int x,int l,int r,int ll,int rr) { if (r<l||rr<l||r<ll) return 0; if (ll<=l&&r<=rr) return t[x]; int mid=l+r>>1,ans=0; if (ll<=mid) ans+=Query(lson,l,mid,ll,rr); if (mid<rr) ans+=Query(rson,mid+1,r,ll,rr); return ans; } int Query(int x,int y) { int fx=top[x],fy=top[y],ans=0; while (fx!=fy) { if (dep[fx]<dep[fy]) swap(x,y),swap(fx,fy); ans+=Query(rt,1,scnt,seg[fx],seg[x]); x=f[fx];fx=top[x]; } if (dep[x]<dep[y]) swap(x,y),swap(fx,fy); return ans+Query(rt,1,scnt,seg[y],seg[x]); } int main() { scanf("%d%d",&n,&m); for (int i=1,u,v;i<n;i++) scanf("%d%d",&u,&v),Add(u,v); for (int i=1;i<=n;i++) scanf("%d",&w[i]); DFS(1,0);top[1]=1;rev[seg[1]=++scnt]=1;DFS(1);Build(rt,1,scnt); for (;m;m--) { int k,a,b; scanf("%d%d%d",&k,&a,&b); if (k==1) Change(rt,1,scnt,seg[a],b); else printf("%d\n",Query(a,b)); } }
在日渐沉没的世界里,我发现了你。