Topic: Given a tree, each point has an integer weight (which can be negative) and requires support for two operations:
1. Add the Chain
2. The sum of the absolute value on the chain
Because the number of add is guaranteed to be non-negative, so a negative count becomes a positive sum of up to times
Tree chain, maintaining the maximum number of negative numbers in the segment tree
I don't know why I wrote two segment trees, and the tle merged two segment trees into one, 7s over.
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define M 100100using namespace STD;structsegtree{Segtree *ls,*rs;Long LongSum,mark;intCntnumber of negative numbers in//intervalpair<int,int> Max_pos;void*operator New(size_t) {StaticSegtree mempool[m<<1],*c=mempool;returnC + +; }voidADD (intXintYLong Longval) {sum+= (y-x+1-2*CNT) *val; Mark+=val;if(Max_pos.first!= (signed)0XEFEFEFEF) Max_pos.first+=val; }voidPUSH_UP (intXintY) {sum=ls->sum+rs->sum; cnt=ls->cnt+rs->cnt; Max_pos=max (Ls->max_pos,rs->max_pos); }voidPush_down (intXintY) {intMid=x+y>>1;if(Mark) {Ls->add (X,mid,mark); Rs->add (mid+1, Y,mark); mark=0; } }voidBuild_tree (intXintYintA[]) {intMid=x+y>>1;if(x==y) {if(a[mid]<0) max_pos=pair<int,int> (a[mid],mid), cnt=1;Elsemax_pos=pair<int,int> (0XEFEFEFEF,0); sum=ABS(A[mid]);return; } (ls=NewSegtree)->build_tree (x,mid,a); (rs=NewSegtree)->build_tree (mid+1, y,a); Push_up (x, y); }voidReverse (intXintYintPOS) {intMid=x+y>>1;if(x==y) {cnt=0; Sum=-sum; max_pos=pair<int,int> (0XEFEFEFEF,0);return; } push_down (x, y);if(Pos<=mid) Ls->reverse (X,mid,pos);ElseRs->reverse (mid+1, Y,pos); Push_up (x, y); }voidADD (intXintYintLintRLong LongVal) {intMid=x+y>>1;if(X==L&&Y==R) {ADD (x,y,val);return; } push_down (x, y);if(R<=mid) Ls->add (x,mid,l,r,val);Else if(L>mid) Rs->add (mid+1, Y,l,r,val);ElseLs->add (X,mid,l,mid,val), Rs->add (mid+1, y,mid+1, R,val); Push_up (x, y); }Long LongQuery (intXintYintLintR) {intMid=x+y>>1;if(X==L&&Y==R)returnSum Push_down (x, y);if(R<=mid)returnLs->query (X,MID,L,R);if(L>mid)returnRs->query (mid+1, y,l,r);returnLs->query (X,mid,l,mid) + rs->query (mid+1, y,mid+1, R); } pair<int,int> Get_pos (intXintYintLintR) {intMid=x+y>>1;if(X==L&&Y==R)returnMax_pos; Push_down (x, y);if(R<=mid)returnLs->get_pos (X,MID,L,R);if(L>mid)returnRs->get_pos (mid+1, y,l,r);returnMax (Ls->get_pos (X,mid,l,mid), Rs->get_pos (mid+1, y,mid+1, R)); }}*tree=NewSegtree;structabcd{intTo,next;} table[m<<1];intHead[m],tot;intN,M,A[M];intFA[M],SON[M],DPT[M],SIZE[M];intPOS[M],TOP[M],_A[M];voidADD (intXintY) {table[++tot].to=y; TABLE[TOT].NEXT=HEAD[X]; Head[x]=tot;}voidDFS1 (intx) {intI dpt[x]=dpt[fa[x]]+1; size[x]=1; for(I=head[x];i;i=table[i].next)if(Table[i].to!=fa[x]) {fa[table[i].to]=x; DFS1 (table[i].to); SIZE[X]+=SIZE[TABLE[I].TO];if(Size[table[i].to]>size[son[x]]) son[x]=table[i].to; }}voidDFS2 (intx) {Static intTintI _A[POS[X]=++T]=A[X];if(SON[FA[X]]==X) top[x]=top[fa[x]];ElseTop[x]=x;if(Son[x]) DFS2 (Son[x]); for(I=head[x];i;i=table[i].next)if(Table[i].to!=fa[x]&&table[i].to!=son[x]) DFS2 (table[i].to);}voidADD (intXintYintZ) {intFx=top[x],fy=top[y]; while(FX!=FY) {if(Dpt[fx]<dpt[fy]) swap (FX,FY), swap (x, y); while(1) {pair<int,int> Temp=tree->get_pos (1, N,pos[fx],pos[x]);if(temp.first+z>=0) Tree->reverse (1, N,temp.second);Else Break; } tree->add (1, n,pos[fx],pos[x],z); X=FA[FX];FX=TOP[X]; }if(Dpt[x]<dpt[y]) swap (x, y); while(1) {pair<int,int> Temp=tree->get_pos (1, N,pos[y],pos[x]);if(temp.first+z>=0) Tree->reverse (1, N,temp.second);Else Break; } tree->add (1, n,pos[y],pos[x],z);}Long LongQuery (intXintY) {intFx=top[x],fy=top[y];Long LongRe=0; while(FX!=FY) {if(Dpt[fx]<dpt[fy]) swap (FX,FY), swap (x, y); Re+=tree->query (1, N,pos[fx],pos[x]); X=FA[FX];FX=TOP[X]; }if(Dpt[x]<dpt[y]) swap (x, y);returnRe+tree->query (1, N,pos[y],pos[x]);}intMain () {intI,p,x,y,z;Cin>>n>>m; for(i=1; i<=n;i++)scanf("%d", &a[i]); for(i=1; i<n;i++) {scanf("%d%d", &x,&y); ADD (x, y); ADD (Y,X); } DFS1 (1);D FS2 (1); Tree->build_tree (1, n,_a); for(i=1; i<=m;i++) {scanf("%d%d%d", &p,&x,&y);if(p==1) {scanf("%d", &z);if(z) Add (x, y, z); }Else{#ifdef POPOQQQ printf("%i64d\n", Query (x, y));#else printf("%lld\n", Query (x, y));#endif} }return 0;}
Bzoj 4127 Abs tree chain split