#include <algorithm> #include <cstdio> #include <cstring> #include <cstdlib> #include < iostream> #include <vector> #include <queue> #include <stack> #include <iomanip> #include <string> #include <climits> #include <cmath> #define MAX 110000#define LL long longusing namespace std; LL n,m; LL ans;struct tree{ll l,r; LL Sum,add;}; Tree tree[max*3];void Pushup (ll x)//update {ll tmp=2*x;tree[x].sum=tree[tmp].sum+tree[tmp+1].sum;} void Pushdown (ll x)//pass tag and update {LL tmp=2*x;tree[tmp].add+=tree[x].add;tree[tmp+1].add+=tree[x].add;tree[tmp].sum+= tree[x].add* (tree[tmp].r-tree[tmp].l+1); tree[tmp+1].sum+=tree[x].add* (tree[tmp+1].r-tree[tmp+1].l+1); Tree[x]. Add=0;} void build (int l,int r,int x) {tree[x].l=l;tree[x].r=r;tree[x].add=0;if (l==r) {scanf ("%lld", &tree[x].sum); return ;} int Tmp=x<<1;int mid= (l+r) >>1;build (l,mid,tmp); build (mid+1,r,tmp+1);p ushup (x); If you assign a value to sum during the build process, remember to pushup}void update (LL l,ll r,ll c,ll x) {if (r<tree[x].l| | L>TREE[X].R) REturn; if (L<=TREE[X].L&&R>=TREE[X].R) {tree[x].add+=c;tree[x].sum+=c* (tree[x].r-tree[x].l+1); return;} if (Tree[x].add) pushdown (x); Need to fragment pass Mark LL tmp=x<<1;update (l,r,c,tmp);//!!! Update (L,R,C,TMP+1);p ushup (x); At this point, the X node sum is not updated sum}void query (LL l,ll r,ll x) {if (r<tree[x].l| | L>TREE[X].R)//The interval to be updated is not in the interval L r TL tr or TL tr l rreturn; if (L<=TREE[X].L&&R>=TREE[X].R)//To update the interval includes the interval l TL TR R{ans+=tree[x].sum;return;} if (Tree[x].add) pushdown (x); LL tmp=x<<1; LL mid= (TREE[X].L+TREE[X].R) >>1;if (r<=mid) query (L,R,TMP); TL L r mid tr (l,r) else if (l>mid) query (l,r,tmp+1); TL Mid l R TR (l,r) else{//Total TL L MID R tr (l,r) query (L,MID,TMP); Left (l,mid) query (mid+1,r,tmp+1); Right (Mid+1,r)}//pushup (x);} int main () {//freopen ("Cin.txt", "R", stdin),//freopen ("Cout.txt", "w", stdout), while (~SCANF ("%lld%lld",&n,& m) {build (1,n,1); char str[5];while (m--) {scanf ("%s", str); if (str[0]== ' Q ') {LL l,r;scanf ("%lld%lld", &l,&r), Ans=0;query (l,r,1);p rintf ("%lld\n", ans);} Else{ll l,r,c;scanf ("%lld%lld%lld", &l,&r,&c); update (l,r,c,1);}} return 0;}
Refined Segment Tree Interval modification section notes