维护序列 (区间乘加,区间查询

# 题意

给定长度为n的序列,有3个操作,分别是

1)给定一个区间[l,r]区间所有数同乘一个数

2)给定区间[l,r]区间所有数同时加一个数

3)给定区间[l,r]问区间所有数的和mod P后的结果

# 题解

pushdown的时候有两个延迟标记,不需要根据操作来分开写,

当乘的时候相当于+0,加的时候乘1

更新延迟标记的时候假设当前的

(x*mul+add)*a=x*mul*a+add*a

标记的更新:

mul=mul*a

add=add*mul+b

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 const int N=1e5+10;
 5 int n,p;
 6 int a[N];
 7 struct node{
 8     int l,r;
 9     ll sum,add,mul;
10 }tr[N*4];
11 void pushup(int u){
12     tr[u].sum=(tr[u<<1].sum+tr[u<<1|1].sum)%p;
13 }
14 void cal(node &t,int add,int mul){
15     t.sum=((ll)t.sum*mul+(ll)(t.r-t.l+1)*add)%p;
16     t.mul=((ll)t.mul*mul)%p;
17     t.add=((ll)t.add*mul + add)%p;
18 }
19 void pushdown(int u) {
20     cal(tr[u<<1],tr[u].add,tr[u].mul);
21     cal(tr[u<<1|1],tr[u].add,tr[u].mul);
22     tr[u].add=0,tr[u].mul=1;
23 }
24 void build(int u,int l,int r){
25     if(l==r){
26         tr[u]={l,r,a[r],0,1};
27         return;
28     }
29     tr[u]={l,r,0,0,1};//pushup 只会更新sum的值,要赋值
30     int mid= l + r >>1;
31     build(u<<1,l,mid);
32     build(u<<1|1,mid+1,r);
33     pushup(u);
34 }
35 void change(int u,int l,int r,int ad,int mu){
36     if(tr[u].l>=l && tr[u].r<=r){
37         cal(tr[u],ad,mu);
38         return;
39     }
40     pushdown(u);
41     int mid=tr[u].l+tr[u].r>>1;
42     if(l <= mid) change(u<<1,l,r,ad,mu);
43     if(r>mid) change(u<<1|1,l,r,ad,mu);
44     pushup(u);
45 }
46 ll ask(int u,int l,int r){
47     if(tr[u].l>=l && tr[u].r <=r)
48         return tr[u].sum;
49     pushdown(u);
50     int mid=tr[u].l+tr[u].r>>1;
51     ll res=0;
52     if(l<=mid) res=ask(u<<1,l,r);
53     if(r>mid) res=(res+ask(u<<1|1,l,r))%p;
54     return res;
55 }
56 int main(){
57     cin>>n>>p;
58     for(int i=1;i<=n;i++)
59         cin>>a[i];
60     build(1,1,n);
61     int m;
62     cin>>m;
63     while(m--){
64         int op,l,r,c;
65         cin>>op>>l>>r;
66         if(op==1){
67             cin>>c;
68             change(1,l,r,0,c);
69         }
70         else if(op==2){
71             cin>>c;
72             change(1,l,r,c,1);
73         }
74         else {
75             cout<<ask(1,l,r)%p<<endl;
76         }
77     }
78 }

猜你喜欢

转载自www.cnblogs.com/hhyx/p/12520732.html