线段树用于维护区间信息,模板使用结构体来表示线段树,这样看起来结构更加清晰,正常使用并不会用结构体。
1 #include<stdio.h> 2 #define maxn 100005 3 #define lll long long 4 struct node{int l,r;lll sum,laz;}; 5 lll ori[maxn]; 6 struct segt 7 { 8 node seg[maxn*6]; 9 lll build(int now)//建立线段树 10 { 11 node t = seg[now]; 12 if(t.l==t.r){seg[now].sum=ori[t.l];return seg[now].sum;} 13 int mid = (t.l+t.r)>>1,lc = now<<1,rc = lc|1; 14 seg[lc].l = t.l; seg[lc].r = mid; 15 seg[rc].l = mid+1; seg[rc].r = t.r; 16 seg[now].sum = build(lc)+build(rc); 17 return seg[now].sum; 18 } 19 void push(int now)//推送懒标记 20 { 21 if(seg[now].laz) 22 { 23 lll lz = seg[now].laz; seg[now].laz = 0; 24 seg[now].sum += lz*(seg[now].r-seg[now].l+1); 25 if(seg[now].l==seg[now].r) return; 26 seg[now<<1].laz += lz; seg[(now<<1)|1].laz += lz; 27 } 28 } 29 void upd(int now,int l,int r,lll w)//区间修改 30 { 31 push(now); 32 if(seg[now].l>r||seg[now].r<l) return; 33 if(l<=seg[now].l&&seg[now].r<=r) {seg[now].laz+=w;push(now);return;} 34 int lc = now<<1,rc = lc|1; 35 upd(lc,l,r,w); upd(rc,l,r,w); 36 seg[now].sum = seg[lc].sum + seg[rc].sum; 37 } 38 lll que(int now,int l,int r)//区间查询 39 { 40 push(now); 41 if(seg[now].l>r||seg[now].r<l) return 0; 42 if(l<=seg[now].l&&seg[now].r<=r) return seg[now].sum; 43 return que(now<<1,l,r) + que((now<<1)|1,l,r); 44 } 45 }T; 46 int n,op; 47 int main() 48 { 49 scanf("%d%d",&n,&op); 50 int i,flag,p,q; lll w; 51 for(i=1;i<=n;i++) scanf("%lld",ori+i); 52 T.seg[1].l = 1; T.seg[1].r= n; 53 T.build(1); 54 for(i=1;i<=op;i++) 55 { 56 scanf("%d%d%d",&flag,&p,&q); 57 if(flag==1) 58 { 59 scanf("%lld",&w); 60 T.upd(1,p,q,w); 61 } 62 else 63 {printf("%lld ",T.que(1,p,q));} 64 } 65 return 0; 66 }