分析
树剖模板……

#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));
}
}
来源:https://www.cnblogs.com/mastervan/p/11149089.html
