## P3833 [SHOI2012] magic tree (the tree split chain template title)

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);
for(int i=1;i<n;i++){
int u,v;
scanf("%d%d",&u,&v);
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 ;
}```

### Guess you like

Origin www.cnblogs.com/zjl192628928/p/11298733.html
Recommended
Ranking
Daily