Description
There is a tree with a number of N, the root of point 1, and the tree point has edge rights. And then there's M-a
operation, divided into three kinds:Action 1: Increase the point weight of a node x by a. Action 2: Add a to the point in a subtree that has a node x as its root. Action 3: Ask a node x to the root of the path in a little bit of the right and. Input
The first line consists of two integers N, M. Represents the number of points and operands.
the next row of N integers represents the initial weights of the nodes in the tree. Next N-1 line three positive integer fr, to, indicating that there is an edge in the tree (FR, to). the next M line, each line represents one operation. Where the first number indicates that the operator has a(1-3), followed by the parameters of the operation (x or x a). Output
For each query operation, output the answer to the query. The answers are separated by line breaks.
Sample Input5 5
1 2 3) 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3Sample Output6
9
13
HINT
For 100% of data, n,m<=100000, and the absolute value of all input data is not
will exceed 10^6.
1#include <iostream>2#include <cstring>3#include <cstdio>4#include <cstdlib>5 using namespacestd;6 Const intmaxn=100010;7 intcnt,fir[maxn],to[maxn<<1],nxt[maxn<<1],n,m;8 voidAddedge (intAintb) {9nxt[++cnt]=fir[a];to[cnt]=b;fir[a]=CNT;Ten } One Long Longkey[maxn],tr[maxn<<2],add[maxn<<2]; A intID[MAXN],FA[MAXN],TOP[MAXN],END[MAXN],SZ[MAXN],SON[MAXN]; - voidPUSH_UP (intx) { -tr[x]=tr[x<<1]+tr[x<<1|1]; the } - voidADD (intXintLintRLong Longd) { -tr[x]+= (r-l+1)*D; -add[x]+=D; + } - voidPush_down (intXintLintR) { + if(Add[x]) { A intMid= (l+r) >>1; atADD (x<<1, l,mid,add[x]); -ADD (x<<1|1, mid+1, r,add[x]); -add[x]=0; - } - } - voidUpdata (intNodeintLintRintAintBLong Longd) { in if(l>=a&&r<=b) { - Add (node,l,r,d); to return; + } - Push_down (node,l,r); the intMid= (l+r) >>1; * if(mid>=a) Updata (node<<1, l,mid,a,b,d); $ if(MID<B) Updata (node<<1|1, mid+1, r,a,b,d);Panax Notoginseng push_up (node); - } the Long LongQuery (intNodeintLintRintAintb) { + if(l>=a&&r<=b)returnTr[node]; A Push_down (node,l,r); the intMid= (l+r) >>1; + Long Longret=0; - if(mid>=a) Ret=query (node<<1, l,mid,a,b); $ if(mid<b) Ret+=query (node<<1|1, mid+1, r,a,b); $ returnret; - } - voidDFS (intx) { thesz[x]=1; - for(intI=fir[x];i;i=Nxt[i]) {Wuyi if(To[i]==fa[x])Continue; thefa[to[i]]=x; - DFS (To[i]); Wusz[x]+=Sz[to[i]]; -Son[x]=sz[son[x]]<sz[to[i]]?To[i]:son[x]; About } $ } - Long LongSolve (inty) { - Long Longret=0; - while(y) { ARet+=query (1,1, N,id[top[y]],id[y]); +y=Fa[top[y]]; the } - returnret; $ } the intcont; the voidDFS2 (intXintTP) { theid[x]=++cont;top[x]=TP; the if(Son[x]) DFS2 (SON[X],TP); - for(intI=fir[x];i;i=Nxt[i]) in if(to[i]!=fa[x]&&to[i]!=Son[x]) the DFS2 (To[i],to[i]); theend[x]=cont; About } the intMain () { theFreopen ("t2.in","R", stdin); theFreopen ("T2.out","W", stdout); +scanf"%d%d",&n,&m); - for(intI=1; i<=n;i++) thescanf"%lld",&key[i]);Bayi the for(intI=1, a,b;i<n;i++){ thescanf"%d%d",&a,&b); - Addedge (A, b); - Addedge (b,a); the } the theDFS (1); theDFS2 (1,1); - the for(intI=1; i<=n;i++) theUpdata (1,1, N,id[i],id[i],key[i]); the intOp,x,a;94 while(m--){ thescanf"%d",&op); the if(op==1){ thescanf"%d%d",&x,&a);98Updata (1,1, n,id[x],id[x],a); About } - Else if(op==2){101scanf"%d%d",&x,&a);102Updata (1,1, n,id[x],end[x],a);103 }104 Else{ thescanf"%d",&x);106printf"%lld\n", Solve (x));107 }108 }109 return 0; the}
Data structure (tree chain): Bzoj 4034: [haoi2015]t2