代码如下
#include <iostream>
#define lc k<<1
#define rc k<<1|1
#define mid ((l+r)>>1)
#define ll long long
using namespace std;
const ll N = 1e6+5;
struct node{
ll sum,add,muti;
}t[N<<2];
ll n,m,a[N],p;
void push_up(ll k){
t[k].sum=t[lc].sum+t[rc].sum;
t[k].sum%=p;
}
void push_down(ll k,ll l,ll r){
t[lc].muti*=t[k].muti;t[rc].muti*=t[k].muti;
t[lc].sum*=t[k].muti;t[rc].sum*=t[k].muti;
t[lc].add*=t[k].muti;t[rc].add*=t[k].muti;
t[lc].add+=t[k].add,t[rc].add+=t[k].add;
t[lc].sum+=t[k].add*(mid-l+1),t[rc].sum+=t[k].add*(r-mid);
t[lc].add%=p;t[lc].muti%=p;t[lc].sum%=p;
t[rc].add%=p;t[rc].muti%=p;t[rc].sum%=p;
t[k].muti = 1;
t[k].add=0;
}
void build(ll k,ll l,ll r){
t[k].muti = 1;
t[k].add = 0;
if(l==r){
t[k].sum = a[l]%p;
return;
}
build(lc,l,mid);
build(rc,mid+1,r);
push_up(k);
}
void change_line(ll k,ll l,ll r,ll L,ll R,ll v){//a[L...R]+=v
if(L<=l&&r<=R){
t[k].add += v;
t[k].sum += (r-l+1)*v;
t[k].add %=p;
t[k].sum %=p;
return;
}
push_down(k,l,r);
if(L<=mid) change_line(lc,l,mid,L,R,v);
if(R>=mid+1) change_line(rc,mid+1,r,L,R,v);
push_up(k);
}
void change_line2(ll k,ll l,ll r,ll L,ll R,ll v){//a[L...R]*=v
if(L<=l&&r<=R){
t[k].add *= v;
t[k].add %=p;
t[k].sum *= v;
t[k].sum %=p;
t[k].muti *= v;
t[k].muti %=p;
return;
}
push_down(k,l,r);
if(L<=mid) change_line2(lc,l,mid,L,R,v);
if(R>=mid+1) change_line2(rc,mid+1,r,L,R,v);
push_up(k);
}
ll query(ll k,ll l,ll r,ll L,ll R){//a[L]+...a[R]
if(L<=l&&r<=R){
return t[k].sum%=p;
}
push_down(k,l,r);
ll ret=0;
if(L<=mid) ret+=query(lc,l,mid,L,R)%p;
if(R>=mid+1) ret+=query(rc,mid+1,r,L,R)%p;
return ret%=p;
}
int main(){
cin>>n>>m>>p;
for(ll i=1;i<=n;i++) cin>>a[i];
build(1,1,n);
ll x,y,z;
while(m--){
cin>>x;
if(x==1){
cin>>x>>y>>z;
change_line2(1,1,n,x,y,z);
}
if(x==2){
cin>>x>>y>>z;
change_line(1,1,n,x,y,z);
}
if(x==3){
cin>>x>>y;
cout<<query(1,1,n,x,y)%p<<endl;
}
}
return 0;
}