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。