"BZOJ-4127" Abs Tree chain split + segment tree (interesting posture)

Source: Internet
Author: User

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)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.