FZU2082树链剖分
简单题。
#include<queue> #include<stack> #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define INF 99999999 #define ll __int64 #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 using namespace std; const int MAXN = 50010; struct node{ int to; int next; }edge[MAXN*3]; int ind,pre[MAXN],top[MAXN],fa[MAXN],siz[MAXN],son[MAXN],w[MAXN],deq[MAXN],fn; int n; ll val[MAXN][3],tree[MAXN<<2]; void add(int x,int y) { edge[ind].to = y; edge[ind].next = pre[x]; pre[x] = ind++; } void dfs1(int rt,int pa,int d) { deq[rt] = d; siz[rt] = 1; son[rt] = 0; fa[rt] = pa; for(int i=pre[rt]; i!=-1; i=edge[i].next){ int t = edge[i].to; if(t != fa[rt]){ dfs1(t,rt,d+1); siz[rt] += siz[t]; if(siz[son[rt]] < siz[t]){ son[rt] = t; } } } } void dfs2(int rt,int tp) { w[rt] = ++fn; top[rt] = tp; if(son[rt] != 0){ dfs2(son[rt],tp); } for(int i=pre[rt]; i!=-1; i=edge[i].next){ int t = edge[i].to; if(t != fa[rt] && t != son[rt]){ dfs2(t,t); } } } /****************************/ void pushup(int rt) { tree[rt] = tree[rt<<1] + tree[rt<<1|1]; } void updata(int p,ll v,int l,int r,int rt) { if(l == r){ tree[rt] = v; return ; } int m = (l+r)/2; if(m >= p){ updata(p,v,lson); } else { updata(p,v,rson); } pushup(rt); } ll query(int L,int R,int l,int r,int rt) { if(L<=l && r<=R){ return tree[rt]; } int m = (l+r)/2; ll ans = 0; if(m >= L){ ans += query(L,R,lson); } if(m < R){ ans += query(L,R,rson); } return ans; } ll lca(int x,int y) { ll ans = 0; while(top[x] != top[y]) { if(deq[top[x]] < deq[top[y]]){ swap(x,y); } ans += query(w[top[x]],w[x],1,fn,1); x = fa[top[x]]; } if(x == y) return ans; if(deq[x] < deq[y]){ swap(x,y); } ans += query(w[son[y]],w[x],1,fn,1); return ans; } int main() { int i,j,m; while(~scanf("%d%d",&n,&m)) { ind = 1; memset(pre,-1,sizeof(pre)); for(i=1; i<n; i++){ int a,b; ll c; scanf("%d %d %I64d",&a,&b,&c); add(a,b); add(b,a); val[i][0] = (ll)a; val[i][1] = (ll)b; val[i][2] = c; } memset(son,0,sizeof(son)); memset(siz,0,sizeof(siz)); dfs1(1,1,1); fn = 0; dfs2(1,1); memset(tree,0,sizeof(tree)); for(i=1; i<n; i++){ if(deq[val[i][0]] < deq[val[i][1]]){ swap(val[i][0],val[i][1]); } updata(w[val[i][0]],val[i][2],1,fn,1); } int t,a,b; while(m--) { scanf("%d%d%d",&t,&a,&b); if(t == 0){ updata(w[val[a][0]],b,1,fn,1); } else { printf("%I64d\n",lca(a,b)); } } } }