We are more and more lazy, even the explanation is not bothered to write, the main idea is to take an interval as a line segment, and then constantly recursive two points finally become the points, the key lies in the Lazy_tag, when you are dealing with the range is completely in the target operating range can be processed with lazy, no longer recursive, thought is such , if you want to, you should go to the first two times, play and understand, and then you can fight.
#include <algorithm>#include<iostream>#include<cstring>#include<cstdlib>#include<cstdio>#include<cmath>#defineL (x) st[x].l#defineR (x) ST[X].R#defineSUM (x) st[x].sum#defineLazy (x) st[x].lazyusing namespaceStd;typedefLong Longll;Const intSize = 1e5 +5;structsegment_tree{intL,r; ll Sum,lazy;} St[size<<2];intA[size];voidBuildint,int,int);voidSpreadint);voidChangeint,int,int,int); ll ask (int,int,int);intMain () {intN, Q; scanf ("%d", &N); for(inti =1; I <= N; i++) scanf ("%d", &A[i]); Build (1,1, N); scanf ("%d",&q); for(inti =0; i < Q; i++){ intO,a, B, C; scanf ("%d%d%d",&o,&a,&C); if(o==1) {scanf ("%d", &c); Change (1, A, b, c); } Elsecout << Ask (1, A, b) << Endl;//printf ("%i64d\n", ask (1, a, b)); } return 0;} voidBuildintXintLintR) {L (x)= L,r (x) =R; if(L = =R) {sum (x)=A[l]; return ; } intMID = L + R >>1; Build (x<<1, L,mid); Build (x<<1|1, Mid +1, R); SUM (x)= SUM (x <<1) + SUM (x <<1|1);}voidSpreadintx) { if(Lazy (x)) {sum (x<<1) + = lazy (x) * (R (x <<1)-L (x <<1) +1); SUM (x<<1|1) + = lazy (x) * (R (x <<1|1)-L (x <<1|1) +1); Lazy (x<<1) +=lazy (x); Lazy (x<<1|1) +=lazy (x); Lazy (x)=0; }}voidChangeintXintLintRintDelta) { if(L <= L (x) && R >=r (x)) {sum (x)+ = Delta * (r (x)-L (x) +1); Lazy (x)+=Delta; return ; } intMID = L (x) + R (x) >>1; Spread (x); if(l <= mid) change (x <<1, L,r,delta); if(R > Mid) change (x <<1|1, L,r,delta); SUM (x)= SUM (x <<1) + SUM (x <<1|1); return ;} ll ask (intXintLintR) { if(L <= L (x) && R >=r (x))returnsum (x); intMID = L (x) + R (x) >>1; ll ans=0; if(L <= mid) ans + = ask (x <<1, L,r); if(R > Mid) ans + = ask (x <<1|1, L,r); returnans;}
Oi template--line segment Tree (segment_tree) O (LG N)