线段树模板

Posted liyian

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线段树模板相关的知识,希望对你有一定的参考价值。

直接上题目链接:https://www.luogu.org/problemnew/show/P3372

技术分享图片
 1 #include<cstdio>
 2 using namespace std;
 3 #define maxn 1000001
 4 long long sum[maxn<<2],add[maxn<<2],a[maxn];
 5 int n,m,kind,x,y,w;
 6 void Build(int l,int r,int s){
 7     if (l==r){
 8         sum[s]=a[l];
 9         return ;
10     }
11     int mid=(l+r)>>1;
12     Build(l,mid,s<<1);
13     Build(mid+1,r,s<<1|1);
14     sum[s]=sum[s<<1]+sum[s<<1|1];
15 }
16 void PushDown(int s,int ln,int rn){
17     if (add[s]){
18         add[s<<1]+=add[s],sum[s<<1]+=add[s]*ln;
19         add[s<<1|1]+=add[s],sum[s<<1|1]+=add[s]*rn;
20         add[s]=0;
21     }
22 }
23 void Update(int L,int R,int c,int l,int r,int s){
24     if (L<=l&&r<=R){
25         add[s]+=c,sum[s]+=c*(r-l+1);
26         return ;
27     }
28     int mid=(l+r)>>1;
29     PushDown(s,mid-l+1,r-mid);
30     if (L<=mid) Update(L,R,c,l,mid,s<<1);
31     if (R>mid) Update(L,R,c,mid+1,r,s<<1|1);
32     sum[s]=sum[s<<1]+sum[s<<1|1];
33 }
34 long long Query(int L,int R,int l,int r,int s){
35     if (L<=l&&r<=R) return sum[s];
36     int m=(l+r)>>1;
37     PushDown(s,m-l+1,r-m);
38     long long ans=0;
39     if (L<=m) ans+=Query(L,R,l,m,s<<1);
40     if (R>m) ans+=Query(L,R,m+1,r,s<<1|1);
41     return ans;
42 }
43 int main(){
44     scanf("%d%d",&n,&m);
45     for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
46     Build(1,n,1);
47     for (int i=1;i<=m;i++){
48         scanf("%d",&kind);
49         if (kind==1){
50             scanf("%d%d%d",&x,&y,&w);
51             Update(x,y,w,1,n,1);
52         }else{
53             scanf("%d%d",&x,&y);
54             printf("%lld
",Query(x,y,1,n,1));
55         }
56     }
57 }
线段树

 

以上是关于线段树模板的主要内容,如果未能解决你的问题,请参考以下文章

线段树模板整理

线段树模板总结

线段树模板

模板线段树-单点修改,区间查询

P3834 模板可持久化线段树 1(主席树)

模板 线段树(部分功能)