Bzoj4034[haoi2015]t2
Test instructions
N-point tree, with point 1 as the root, and the tree point has edge rights. Three operations: Add a node to the point of a, a node is the root of the sub-tree a bit of the right to increase a, ask a node to the root of the path of a bit of the right and.
Exercises
The subject chain can be cross-sectioned. The second operation only finds the node with the largest China in the chain each time the chain is constructed, and then the interval is modified. I hear the positive solution is a DFS sequence, but I won't.
Code:
1#include <cstdio>2#include <cstring>3#include <algorithm>4 #defineInc (I,J,K) for (int i=j;i<=k;i++)5 #defineMAXN 2000006 #definell Long Long7 using namespacestd;8 9 structe{intT,n;}; e ES[MAXN];intESS,G[MAXN];Ten voidPeintFintT) {es[++ess]= (e) {t,g[f]}; g[f]=ess; es[++ess]= (e) {f,g[t]}; g[t]=ess;} One intl[maxn*4],r[maxn*4],ch[maxn*4][2],FA[MAXN],DEP[MAXN],POS[MAXN],TOP[MAXN],SZ[MAXN],SGS,MX[MAXN]; All v[maxn][2],sm[maxn*4],tg[maxn*4]; - voidDfsintx) { -sz[x]=1; for(intI=G[X];I;I=ES[I].N)if(es[i].t!=Fa[x]) { theFa[es[i].t]=x; dep[es[i].t]=dep[x]+1; DFS (ES[I].T); sz[x]+=sz[es[i].t]; - } - } - voidBuildchain (intXintPS) { +POS[X]=MX[X]=++SGS; v[sgs][1]=v[x][0]; Top[x]=ps;intmx1=0, mx2=0; - for(intI=G[X];I;I=ES[I].N)if(es[i].t!=fa[x]&&mx2<sz[es[i].t]) mx2=sz[es[i].t],mx1=es[i].t; + if(MX1) Buildchain (mx1,ps), mx[x]=Max (mx[x],mx[mx1]); A for(intI=G[X];I;I=ES[I].N)if(es[i].t!=fa[x]&&es[i].t!=mx1) atBuildchain (es[i].t,es[i].t), mx[x]=Max (mx[x],mx[es[i].t]); - } - voidPushdown (intx) { - if(x&&Tg[x]) { - intlc=ch[x][0],rc=ch[x][1]; - if(LC) sm[lc]+= (r[lc]-l[lc]+1) *tg[x],tg[lc]+=Tg[x]; in if(RC) sm[rc]+= (r[rc]-l[rc]+1) *tg[x],tg[rc]+=Tg[x]; -tg[x]=0; to } + } - voidBuildintXintLintR) { the if(l==r) sm[x]=v[l][1],ch[x][0]=ch[x][1]=0, L[x]=r[x]=l;Else{ *ch[x][0]=x<<1, l[x]=l,ch[x][1]=x<<1|1, R[x]=r;intM= (l+r) >>1; $Build (ch[x][0],L,M); Build (ch[x][1],m+1, R); sm[x]=sm[ch[x][0]]+sm[ch[x][1]];Panax Notoginseng } - } thell query (intXintLintR) { + pushdown (x); A if(L<=L[X]&&R[X]<=R)returnSM[X];Else{ thell q=0;intM= (L[x]+r[x]) >>1;if(l<=m) Q+=query (ch[x][0],L,R);if(m<r) Q+=query (ch[x][1],l,r); + returnQ; - } $ } $ voidAddintXintLintr,ll val) { - pushdown (x); - if(l<=l[x]&&r[x]<=r) tg[x]+=val,sm[x]+= (r[x]-l[x]+1) *val;Else{ the intM= (L[x]+r[x]) >>1;if(l<=m) Add (ch[x][0],l,r,val);if(m<r) Add (ch[x][1],l,r,val); -sm[x]=sm[ch[x][0]]+sm[ch[x][1]];Wuyi } the } -inline ll Querysum (intx) {ll q=0; while(x) Q+=query (1, Pos[top[x]],pos[x]), x=fa[top[x]];returnq;} Wu voidInit1 () {ess=0; Memset (G,0,sizeof(g));} - voidInit2 () {dep[1]=fa[1]=0; Dfs1); sgs=0; Buildchain (1,1); Build1,1, SGS);} About intn,m; $ intMain () { - //freopen ("Test.txt", "R", stdin); -scanf"%d%d", &n,&m); Inc (I,1, N) scanf ("%lld", &v[i][0]); Init1 (); -Inc (I,1, N-1){intb; scanf"%d%d",&a,&b); PE (A, b);} Init2 (); AInc (I,1, M) { + intOpt,x;ll y; scanf"%d%d",&opt,&x); the if(opt==1) scanf ("%lld", &y), add (1, pos[x],pos[x],y); - if(opt==2) scanf ("%lld", &y), add (1, pos[x],mx[x],y); $ if(opt==3) printf ("%lld\n", Querysum (x)); the } the return 0; the}
20160425
Bzoj4034[haoi2015]t2