线段树

以上摘自LYH大佬课件;

可以实现:

  1.区间加;

  2.查询区间和;

  粘代码:

  P3372 【模板】线段树 1

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 typedef long long ll;
 6 using namespace std;
 7 const int maxn=100009;
 8 struct node{
 9     ll l,r,sum,lazy;
10 }tr[maxn<<2];
11 ll a[maxn],n,m;
12 void build_(ll p,ll l,ll r)//建树
13 {
14     tr[p].l=l;
15     tr[p].r=r;
16     if(l==r) 
17     {
18         tr[p].sum=a[l];
19         return ;
20     }
21     ll mid=(l+r)>>1;
22     build_(p<<1,l,mid);
23     build_(p<<1|1,mid+1,r);
24     tr[p].sum=tr[p<<1].sum+tr[p<<1|1].sum;
25 } 
26 void add_(ll p,ll l,ll r,ll d)//区间加
27 {
28     if(tr[p].l==l&&tr[p].r==r)
29     {
30         tr[p].sum+=d*(r-l+1);
31         tr[p].lazy+=d;
32         return ;
33     }
34     ll mid=(tr[p].l+tr[p].r)>>1;
35     if(tr[p].lazy)//lazy下传
36     {
37         add_(p<<1,tr[p<<1].l,tr[p<<1].r,tr[p].lazy);
38         add_(p<<1|1,tr[p<<1|1].l,tr[p<<1|1].r,tr[p].lazy);
39         tr[p].lazy=0;
40     }
41     if(r<=mid) add_(p<<1,l,r,d);
42     else if(l>mid) add_(p<<1|1,l,r,d);
43     else
44     {
45         add_(p<<1,l,mid,d);
46         add_(p<<1|1,mid+1,r,d);
47     }
48     tr[p].sum=tr[p<<1].sum+tr[p<<1|1].sum;//记得要上传新值
49 }
50 ll ask_(ll p,ll l,ll r)//询问区间和
51 {
52     if(tr[p].l==l&&tr[p].r==r) return tr[p].sum;
53     if(tr[p].lazy)//下传lazy标记
54     {
55         add_(p<<1,tr[p<<1].l,tr[p<<1].r,tr[p].lazy);
56         add_(p<<1|1,tr[p<<1|1].l,tr[p<<1|1].r,tr[p].lazy);
57         tr[p].lazy=0;
58     }
59     ll sum=0;
60     ll mid=(tr[p].l+tr[p].r)>>1;
61     if(r<=mid) sum+=ask_(p<<1,l,r);
62     else if(l>mid) sum+=ask_(p<<1|1,l,r);
63     else
64     {
65         sum+=ask_(p<<1,l,mid);
66         sum+=ask_(p<<1|1,mid+1,r);
67     } 
68     return sum;
69 }
70 int main()
71 {
72     scanf("%lld%lld",&n,&m);
73     for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
74     build_(1,1,n);
75     for(int i=1;i<=m;i++)
76     {
77         ll aa,bb,cc,k;
78         scanf("%lld",&aa);
79         if(aa==1)
80         {
81             scanf("%lld%lld%lld",&bb,&cc,&k);
82             add_(1,bb,cc,k);
83         }
84         if(aa==2)
85         {
86             scanf("%lld%lld",&bb,&cc);
87             printf("%lld
",ask_(1,bb,cc));
88         }
89     }
90     return 0;
91 } 

 感谢GMK大佬的帮助。

原文地址:https://www.cnblogs.com/sdfzjdx/p/10348387.html