Topic links: https://www.luogu.org/problem/P3833
Title effect: a containing tree has n nodes, each node is initially 0, the following two operations:
1.Add uvd represents the value of all the nodes on the path between u and v are plus d.
2.Query u represents the current fruit trees, to the point u rooted sub-tree, the fruit of a total of how many?
Outline of Solution: chain split tree board, particularly to see code comments
Code:
#include <bits / STDC ++ H.> the using namespace STD; typedef Long Long LL; const int MAXN = 100005 ; int TOT, CNT, head [MAXN], n-, m, V [MAXN]; LL Tree [MAXN * . 4 ] , the lazy [* MAXN . 4 ]; int D [MAXN], size [MAXN], Son [MAXN], ID [MAXN], RK [MAXN], FA [MAXN], Top [MAXN]; // size [I] is the number of nodes of subtree i, top [i] where i is the top of the heavy chain, son [i] is the number of heavy son i // D [i] is the true depth of the node i, id [i] is the i the new number, fa [i] is the number i father struct Edge { int V, Next; } Edge [MAXN << . 1 ]; void the Add (int U, int V) { Edge [TOT] .v = V; Edge [TOT] .next = head [U]; head [U] = TOT ++ ; } void DFS1 ( int U, int pre) { // first dfs seeking over a depth of each node, a parent node, the size of the subtrees where D [U] = D [pre] + . 1 ; FA [U] = pre; size [U] = . 1 ; for ( int I = head [U ];! = I - . 1 ; I = Edge [I] .next) { int V = Edge [I] .v; IF (V =! pre) { DFS1 (V, U); size [U] + = size [V]; IF (size [Son [U]] <size [V]) Son [U] = V; } } } void DFS2 ( int U, int TP) { // find each new node number and weight of the heavy chain where the top and son top [U] = TP, ID [U] = CNT ++, RK [CNT] = U; IF (son [U]) DFS2 (son [U], TP); // start and re-son node dfs order to ensure that all nodes on a continuous heavy chain to heavy chain may be maintained by a segment tree information for ( int I = head [U]; I ! = - . 1 ; I = Edge [I] .next) { int V = Edge [I] .v; IF (V FA = [U] = V &&!!son[u]) dfs2(v,v); } } void pushup(int rt){ tree[rt]=tree[rt<<1]+tree[rt<<1|1]; } void pushdown(int l,int r,int rt){ if(lazy[rt]){ tree[rt<<1]=tree[rt<<1]+lazy[rt]*l; tree[rt<<1|1]=tree[rt<<1|1]+lazy[rt]*r; lazy[rt<<1]+=lazy[rt]; lazy[rt<<1|1]+=lazy[rt]; lazy[rt]=0; } } void build(int l,int r,int rt){ lazy[rt]=0; if(l==r){ tree[rt]=v[rk[l]]; return; } int mid=l+r>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); pushup(rt); } void update(int L,int R,int val,int l,int r,int rt){ if(L<=l&&R>=r){ tree[rt]+=1ll*(r-l+1)*val; lazy[rt]+=val; return; } int mid=l+r>>1; pushdown(mid-l+1,r-mid,rt); if(mid>=L) update(L,R,val,l,mid,rt<<1); if(mid<R) update(L,R,val,mid+1,r,rt<<1|1); pushup(rt); } ll query(int L,int R,int l,int r,int rt){ if(L<=l&&R>=r) return tree[rt]; int mid=l+r>>1; ll res=0; pushdown(mid-l+1,r-mid,rt); if(mid>=L) res+=query(L,R,l,mid,rt<<1); IF (MID <R & lt) RES + = Query (L, R & lt, MID + . 1 , R & lt, RT << . 1 | . 1 ); return RES; } void Updates ( int x, int y, int Val) { // Modify x to y value of the shortest path the while (Top [X]! = Top [Y]) { // not the same heavy chain to jump up IF (D [Top [X]] < D [Top [Y]]) the swap (X, Y); Update (ID [top [X]], ID [X], Val, . 1 , n-, . 1 ); X = FA [top [X]]; // jump to the top of the heavy chain of the parent node } IF (ID [X]> ID [Y]) the swap (X, Y); //Two nodes in the same heavy chain, but may not be the same node Update (ID [X], ID [Y], Val, . 1 , n-, . 1 ); } LL ASK ( int X, int Y) { // query x to y shortest path value LL RES = 0 ; the while (! Top [x] = Top [y]) { IF (D [Top [x]] < D [Top [y]]) the swap (x, y) ; RES + = Query (ID [Top [X]], ID [X], . 1 , n-, . 1 ); X = FA [Top [X]]; } IF (ID [X]> ID [Y]) the swap (X, Y); RES + = Query (ID [X], ID [Y], . 1 , n-, . 1); return res; } int main(){ scanf("%d",&n); memset(head,-1,sizeof(head)); for(int i=1;i<n;i++){ int u,v; scanf("%d%d",&u,&v); u++; v++; add(u,v); } scanf("%d",&m); cnt=0,tot=0; dfs1(1,0),dfs2(1,1); build(1,n,1); while(m--){ char op[10]; int l,r,rt,val; scanf("%s",op); if(op[0]=='A'){ scanf("%d%d%d",&l,&r,&val); l++; r++; Updates (L, R & lt, Val); } the else { Scanf ( " % D " , & RT); RT ++ ; the printf ( " % LLD \ n- " , Query (ID [RT], ID [RT] + size [RT] - . 1 , . 1 , n-, . 1 )); // since the size of a sub-tree is the size [rt], the starting point is a number from id [rt] so from id [rt] to id [rt] + size [rt ] - . 1 } } return 0 ; }