乘法懒标记初始化为1了,向下传也先乘后加了
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e5;
int n,q,mod,a[N];
struct segment_tree{ int sum,lazy_mul,lazy_add; }t[N<<2];
void build(int p,int l,int r){
t[p].lazy_mul=1;
if(l==r){
t[p].sum=a[l];
return;
}
int lson=p<<1,rson=p<<1|1,mid=l+(r-l)/2;
build(lson,l,mid);
build(rson,mid+1,r);
t[p].sum=(t[lson].sum+t[rson].sum)%mod;
}
void push_down(int p,int l,int r){
int lson=p<<1,rson=p<<1|1,mid=l+(r-l)/2;
int add=t[p].lazy_add,mul=t[p].lazy_mul;
if(mul!=0&&mul!=1){
t[lson].lazy_mul*=mul,t[lson].lazy_mul%=mod;
t[rson].lazy_mul*=mul,t[rson].lazy_mul%=mod;
t[lson].lazy_add*=mul,t[lson].lazy_add%=mod;
t[rson].lazy_add*=mul,t[rson].lazy_add%=mod;
t[lson].sum*=mul; t[lson].sum%=mod;
t[rson].sum*=mul; t[rson].sum%=mod;
t[p].lazy_mul=1;
}
if(add!=0){
t[lson].lazy_add+=add,t[lson].lazy_add%=mod;
t[rson].lazy_add+=add,t[rson].lazy_add%=mod;
t[lson].sum+=(mid-l+1)*add%mod; t[lson].sum%=mod;
t[rson].sum+=(r-mid)*add%mod; t[rson].sum%=mod;
t[p].lazy_add=0;
}
}
void update(int p,int l,int r,int ul,int ur,int val,bool flag){
if(ul<=l&&r<=ur){
if(flag){
t[p].sum+=(r-l+1)*val%mod; t[p].sum%=mod;
t[p].lazy_add+=val; t[p].lazy_add%=mod;
}else{
t[p].sum*=val; t[p].sum%=mod;
t[p].lazy_add*=val; t[p].lazy_add%=mod;
t[p].lazy_mul*=val; t[p].lazy_mul%=mod;
}
return;
}
push_down(p,l,r);
int lson=p<<1,rson=p<<1|1,mid=l+(r-l)/2;
if(ul<=mid) update(lson,l,mid,ul,ur,val,flag);
if(ur>mid) update(rson,mid+1,r,ul,ur,val,flag);
t[p].sum=(t[lson].sum+t[rson].sum)%mod;
}
int query(int p,int l,int r,int ql,int qr){
if(ql<=l&&r<=qr) return t[p].sum%mod;
int lson=p<<1,rson=p<<1|1,mid=l+(r-l)/2;
push_down(p,l,r);
int ans=0;
if(ql<=mid) ans+=query(lson,l,mid,ql,qr),ans%=mod;
if(qr>mid) ans+=query(rson,mid+1,r,ql,qr),ans%=mod;
return ans%mod;
}
signed main(){
cin>>n>>q>>mod;
for(int i=1;i<=n;i++) cin>>a[i],a[i]%=mod;
build(1,1,n);
while(q--){
int op,x,y,k; cin>>op>>x>>y;
if(op==1){
cin>>k;
update(1,1,n,x,y,k%mod,false);
}else if(op==2){
cin>>k;
update(1,1,n,x,y,k%mod,true);
}else{
cout<<query(1,1,n,x,y)<<"\n";
}
}
return 0;
}