4127:abs time limit:40 Sec Memory limit:256 MB
submit:381 solved:132
[Submit] [Status] [Discuss] Description
Given a tree, the design data structure supports the following operations
1 U v D means the path (U,V) plus D
2 U v indicates the sum of the absolute values of the point weights on the query path (U,V)
Input
First row two integers n and m, representing the number of nodes and operands
Next line n integer a_i, representing the weight of the point I
Next n-1 line, two integers per line u,v indicates the existence of one (U,V) edge
Next M line, one operation per line, input format See topic Description
Output
Output answers for each query
Sample Input4 4
-4 1 5-2
1 2
2 3
3 4
2 1 3
1 1 4 3
2 1 3
2 3 4Sample Output10
13
9HINT
For 100% of data, N,m <= 10^5 and 0<= d,|a_i|<= 10^8
SourceSolution
Tree chain splitting Obviously, the problem of the tree path is transformed into a sequence problem
The segment tree then maintains the absolute value of the interval weights and supports interval plus
Note delta>=0 This condition, that is, the 1 operation guarantees that the addend is not negative, that is, the actual value does not decrease
So the line tree maintains something:
L,r the left and right end points, maxf interval maximum negative number, num interval positive number-negative number, tag interval plus mark; sum interval absolute value and
The significance of the MAXF is that for the interval plus Delta, then if the maxf+delta<0 is obviously a variable number after 1 operation, for the maintenance of absolute value and will inevitably make an impact, so used to judge
The significance of NUM is to calculate the change of sum, which can also be considered to maintain a positive number and a negative number, but the code is more inconvenient.
The meaning of tag is that if the interval +delta does not occur (i.e. maxf+delta<0| | maxf>=0), you can mark it directly, or you'll need to lower the tag to the leaf node and update the answer up
Code
#include <iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>using 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;}#defineMAXN 110000intN,M,A[MAXN];structedgenode{intTo,next;} edge[maxn<<1];intHead[maxn],cnt=1;voidAddintUintV) {cnt++; edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=CNT;}voidInsertintUintv) {Add (u,v); add (v,u);}//----------------------------------------------------------------------------------intSIZE[MAXN],FA[MAXN],DEEP[MAXN],SON[MAXN],PL[MAXN],SZ,PRE[MAXN],TOP[MAXN],PR[MAXN];voidDfs_1 (intNow ) {Size[now]=1; for(intI=head[now]; I I=edge[i].next)if(edge[i].to!=Fa[now]) {Fa[edge[i].to]=Now ; Deep[edge[i].to]=deep[now]+1; Dfs_1 (edge[i].to); if(Size[son[now]]<size[edge[i].to]) son[now]=edge[i].to; Size[now]+=Size[edge[i].to]; }}voidDfs_2 (intNowintchain) {Pl[now]=++sz; Pre[sz]=a[now]; top[now]=chain; if(Son[now]) dfs_2 (Son[now],chain); for(intI=head[now]; I I=edge[i].next)if(Edge[i].to!=son[now] && edge[i].to!=Fa[now]) dfs_2 (edge[i].to,edge[i].to); Pr[now]=sz;}//----------------------------------------------------------------------------------structtreenode{intL,r;Long LongMaxf,tag,sum,num; voidADD (intk) {if(k<0) maxf=k,sum=-k,num=-1; Elsemaxf=0, sum=k,num=1; Tag=0; }}TREE[MAXN<<2];Long LongMAXF (Long LongXLong Longy) { if(x>=0&& y>=0)return 0; if(x>=0|| y>=0)returnmin (x, y); returnMax (x, y);}voidUpdate (intNow ) {TREE[NOW].MAXF=MAXF (tree[now<<1].maxf,tree[now<<1|1].MAXF); Tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum; Tree[now].num=tree[now<<1].num+tree[now<<1|1].num;}voidBuildtree (intNowintLintR) {TREE[NOW].L=l,tree[now].r=R; if(L==R) {Tree[now]. ADD (Pre[l]);return;} intMid= (l+r) >>1; Buildtree ( now<<1, L,mid); Buildtree (now<<1|1, mid+1, R); Update (now);}voidPushdown (intNow ) { if(!tree[now].tag | | tree[now].l==tree[now].r)return; intTag=tree[now].tag; tree[now].tag=0; Tree[now<<1].maxf+=tag; tree[now<<1].sum+=tree[now<<1].num*tag; tree[now<<1].tag+=tag; Tree[now<<1|1].maxf+=tag; tree[now<<1|1].sum+=tree[now<<1|1].num*tag; tree[now<<1|1].tag+=tag;}voidChange (intNowintLintRintD) { intL=tree[now].l,r=TREE[NOW].R; if(L<=l && r>=r && (tree[now].maxf>=0|| tree[now].maxf+d<0) ) {TREE[NOW].MAXF+=d; tree[now].sum+= (Long Long) Tree[now].num*d; Tree[now].tag+=d;return;} if(L==R) {Tree[now]. ADD (TREE[NOW].MAXF+D);return;} Pushdown (now); intMid= (l+r) >>1; if(L<=mid) Change (now<<1, l,r,d); if(R>mid) Change (now<<1|1, l,r,d); Update (now);}Long LongQuery (intNowintLintR) {pushdown (now); intL=tree[now].l,r=TREE[NOW].R; if(L<=l && r>=r)returntree[now].sum; intMid= (l+r) >>1;Long LongRe=0; if(L<=mid) Re+=query (now<<1, L,r); if(R>mid) Re+=query (now<<1|1, L,r); returnre;}voidDeBug (intNow ) { intL=tree[now].l,r=TREE[NOW].R; if(L==R) {printf ("l==r=%d val=%d maxf=%lld tag=%lld sum=%lld num=%lld\n", L,a[l],tree[now].maxf,tree[now].tag,tree[now].sum,tree[now].num);return;} intMid= (l+r) >>1; DeBug ( now<<1); DeBug (now<<1|1); }//----------------------------------------------------------------------------------voidSolve_1 (intXintYintD) { while(top[x]!=Top[y]) { if(deep[top[x]]<Deep[top[y]]) swap (x, y); Change (1, pl[top[x]],pl[x],d); X=Fa[top[x]]; } if(deep[x]>Deep[y]) swap (x, y); Change (1, pl[x],pl[y],d);}Long LongSolve_2 (intXinty) { Long LongRe=0; while(top[x]!=Top[y]) { if(deep[top[x]]<Deep[top[y]]) swap (x, y); Re+=query (1, pl[top[x]],pl[x]); X=Fa[top[x]]; } if(deep[x]>Deep[y]) swap (x, y); Re+=query (1, Pl[x],pl[y]); returnre;}//----------------------------------------------------------------------------------intMain () {//freopen ("4127.in", "R", stdin);//freopen ("4127.out", "w", stdout);N=read (), m=read (); for(intI=1; i<=n; i++) a[i]=read (); for(intU,v,i=1; i<=n-1; i++) U=read (), v=read (), insert (U,V); Dfs_1 (1); Dfs_2 (1,1); Buildtree (1,1, N); intopt,u,v,w; while(m--) {opt=read (); //DeBug (1); if(opt==1) U=read (), V=read (), w=read (), solve_1 (U,V,W); ElseU=read (), V=read (), printf ("%lld\n", solve_2 (u,v)); } return 0;}
This road essay, two days ago Yveh and Etienne wrote half a day more, Dcrusher uncle taunt them, I for their disobedience, and then I determined to write 1 hours, and then adjusted for 3 hours .... Find self-confidence to write a good chain cut less hit a word mdzz
(plus the provincial team training, the third violence hit 70% to eat, come back lazy to play, experience the pleasure of continuous rolling rough)
Find that their constant is close to Etienne ... It's slower than a 100ms.
"BZOJ-4127" Abs Tree chain split + segment tree (interesting posture)