线段树区间修改+查询区间和

Posted st-lovaer

tags:

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

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=1e5+10;
 4 int a[maxn];
 5 int sum[maxn<<2],exc[maxn<<2];
 6 void maintain(int k)
 7 {
 8     sum[k]=sum[k<<1]+sum[k<<1|1];
 9 }
10 void pushdown(int lenl,int lenr,int k)//标记下放,并更细节点信息
11 {
12     if(exc[k]){
13         exc[k<<1]=exc[k];
14         exc[k<<1|1]=exc[k];
15         sum[k<<1]=exc[k]*lenl;
16         sum[k<<1|1]=exc[k]*lenr;
17         exc[k]=0;
18     }
19 }
20 void build(int l,int r,int k)
21 {
22     if(l>r)
23         return ;
24     if(l==r){
25         sum[k]=a[l];
26         exc[k]=0;
27         return ;
28     }
29     int mid=(l+r)>>1;
30     build(l,mid,k<<1);
31     build(mid+1,r,k<<1|1);
32     maintain(k);
33 }
34 void change(int l,int r,int cl,int cr,int k,int newp)
35 {
36     if(l>r||cl>r||cr<l)
37         return ;
38     if(l>=cl&&r<=cr){
39         sum[k]=newp*(r-l+1);//在发现现在区域小于需要更新区域时
40         exc[k]=newp;//更新节点的结果,并增加延迟标记exc,用于之后的标记下放
41         return ;
42     }
43     int mid=(l+r)>>1;
44     pushdown(mid-l+1,r-mid,k);
45     change(l,mid,cl,cr,k<<1,newp);
46     change(mid+1,r,cl,cr,k<<1|1,newp);
47     maintain(k);
48 }
49 int query(int l,int r,int ql,int qr,int k)
50 {
51     if(l>r||ql>r||qr<l)
52         return 0;
53     if(l>=ql&&r<=qr)
54         return sum[k];
55     int mid=(l+r)>>1,ans=0;
56     pushdown(mid-l+1,r-mid,k);//每一层询问执行到这一步,为了下一次递归更新叶节点信息
57     if(mid>=l)
58         ans+=query(l,mid,ql,qr,k<<1);
59     if(mid<r)
60         ans+=query(mid+1,r,ql,qr,k<<1|1);
61     return ans;
62 }
63 int main()
64 {
65     ios::sync_with_stdio(false);
66     //freopen("in.txt","r",stdin);
67     int n,m,cmd,l,r,newp;
68     cin>>n;
69     for(int i=1;i<=n;++i)
70         cin>>a[i];
71     build(1,n,1);
72     cin>>m;
73     for(int i=0;i<m;++i){
74         cin>>cmd>>l>>r;
75         if(cmd){
76             cin>>newp;
77             change(1,n,l,r,1,newp);
78         }else
79             cout<<query(1,n,l,r,1)<<endl;
80     }
81     return 0;
82 }

模板:
模板的情况是询问区间里的所有元素的和,修改是将区间的元素全部改成newp。

以上是关于线段树区间修改+查询区间和的主要内容,如果未能解决你的问题,请参考以下文章

数据结构线段树 (定义 & 点修改/区间查询)

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

线段树详解

线段树 建树 单点修改 点点/区间查询

线段树区间修改和查询和单点查询(线段树模板1)

线段树区间修改+查询区间和