4034: [Haoi2015]t2
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: Operation 1: The point of a node x to increase the right of 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. The first number represents the type of operation (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.
Source
Exercises
It's a naked question,
Code from Hzwer
#include <cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#definell Long Long#defineINF 1000000000#defineMoD 1000000000using namespacestd;intRead () {intx=0, f=1;CharCh=GetChar (); while(ch<'0'|| Ch>'9'){if(ch=='-') f=-1; ch=GetChar ();} while(ch>='0'&&ch<='9') {x=x*Ten+ch-'0'; ch=GetChar ();} returnx*F;}intn,m,cnt;intlast[100005];intid,pos[100005],mx[100005],v[100005];intbl[100005],size[100005],fa[100005];ll tag[400005],sum[400005];structedge{intTo,next;} e[200005];voidInsertintUintv) {e[++cnt]= (Edge) {v,last[u]};last[u]=CNT; e[++cnt]= (Edge) {u,last[v]};last[v]=CNT;}voidDfsintx) {Size[x]=1; for(intI=last[x];i;i=e[i].next)if(e[i].to!=Fa[x]) {Fa[e[i].to]=x; DFS (E[I].TO); SIZE[X]+=Size[e[i].to]; }}voidDFS2 (intXintcha) {Bl[x]=cha;pos[x]=mx[x]=++ID; intk=0; for(intI=last[x];i;i=e[i].next)if(e[i].to!=fa[x]&&size[e[i].to]>Size[k]) k=e[i].to; if(k) {DFS2 (K,cha); Mx[x]=Max (mx[x],mx[k]); } for(intI=last[x];i;i=e[i].next)if(e[i].to!=fa[x]&&e[i].to!=k) {DFS2 (e[i].to,e[i].to); MX[X]=Max (mx[x],mx[e[i].to]); }}voidPushdown (intLintRintk) { if(L==R)return; intMid= (l+r) >>1; ll t=tag[k];tag[k]=0; Tag[k<<1]+=t;tag[k<<1|1]+=T; Sum[k<<1]+=t* (mid-l+1); Sum[k<<1|1]+=t* (Rmid);}voidAddintKintLintRintXinty,ll val) { if(Tag[k]) pushdown (l,r,k); if(L==X&&Y==R) {tag[k]+=val;sum[k]+= (r-l+1) *val;return;} intMid= (l+r) >>1; if(x<=mid) Add (k<<1, L,mid,x,min (Mid,y), Val); if(y>=mid+1) Add (k<<1|1, mid+1, R,max (mid+1, X), y,val); SUM[K]=sum[k<<1]+sum[k<<1|1];} ll query (intKintLintRintXinty) { if(Tag[k]) pushdown (l,r,k); if(L==X&&Y==R)returnSum[k]; intMid= (l+r) >>1; ll ans=0; if(x<=mid) ans+=query (k<<1, L,mid,x,min (mid,y)); if(y>=mid+1) ans+=query (k<<1|1, mid+1, R,max (mid+1, x), y); returnans;} ll query (intx) {ll ans=0; while(bl[x]!=1) {ans+=query (1,1, n,pos[bl[x]],pos[x]); X=Fa[bl[x]]; } ans+=query (1,1N1, pos[x]); returnans;}intMain () {n=read (); m=read (); for(intI=1; i<=n;i++) v[i]=read (); for(intI=1; i<n;i++) { intU=read (), v=read (); Insert (U,V); } DFS (1); DFS2 (1,1); for(intI=1; i<=n;i++) Add (1,1, N,pos[i],pos[i],v[i]); intOpt,x,a; while(m--) {opt=read (); x=read (); if(opt==1) {a=read (); Add (1,1, N,pos[x],pos[x],a); } if(opt==2) {a=read (); Add (1,1, N,pos[x],mx[x],a); } if(opt==3) printf ("%lld\n", query (x)); } return 0;}
Bzoj 4034: [Haoi2015]t2 tree Chain split