RT,其他点全WA
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m,a[8000005],sum[8000005],add[8000005],mu[8000005],mod;
//mod是模数 sum是线段树数组 add是加法标记 mu 是乘法标记
void build(int l,int r,int k){//建树
mu[k]=1,add[k]=0;
if(l==r){
sum[k]=a[l]%mod;
return;
}
int mid=(l+r)/2;
build(l,mid,k*2);
build(mid+1,r,k*2+1);
sum[k]=(sum[k*2]%mod+sum[k*2+1]%mod)%mod;
}
void Add1(int k,int l,int r,int v){//加
add[k]=(add[k]%mod+v%mod)%mod;
sum[k]=(sum[k]%mod+((r-l+1)*v)%mod)%mod;
}
void Add2(int k,int l,int r,int v){//乘
add[k]=((add[k]%mod)*(v%mod))%mod;
mu[k]=((mu[k]%mod)*(v%mod))%mod;
sum[k]=((sum[k]%mod)*(v%mod))%mod;
}
void down(int k,int l,int r){
int mid=(l+r)/2;
sum[k*2]=((sum[k*2]%mod)*(mu[k]%mod))%mod;
sum[k*2]=(sum[k*2]%mod+((mid-l+1)*add[k])%mod)%mod;
//左边更新
sum[k*2+1]=((sum[k*2+1]%mod)*(mu[k]%mod))%mod;
sum[k*2+1]=(sum[k*2+1]%mod+((r-(mid+1)+1)*add[k])%mod)%mod;
//右边更新
mu[k*2]=((mu[k*2]%mod)*(mu[k]%mod))%mod;
mu[k*2+1]=((mu[k*2+1]%mod)*(mu[k]%mod))%mod;
//乘法标记下传
add[k*2]=(add[k*2]%mod+add[k]%mod)%mod;
add[k*2+1]=(add[k*2+1]%mod+add[k]%mod)%mod;
//加法标记下传
add[k]=0;
mu[k]=1;
}
void updata1(int k,int l,int r,int x,int y,int v){//区间加
if(r<x||l>y)return;
if(l>=x&&r<=y){
Add1(k,l,r,v);
return;
}
int mid=(l+r)/2;
down(k,l,r);
updata1(k*2,l,mid,x,y,v);
updata1(k*2+1,mid+1,r,x,y,v);
sum[k]=(sum[k*2]%mod+sum[k*2+1]%mod)%mod;
return;
}
void updata2(int k,int l,int r,int x,int y,int v){//区间乘
if(r<x||l>y)return;
if(l>=x&&r<=y){
Add2(k,l,r,v);
return;
}
int mid=(l+r)/2;
down(k,l,r);
updata2(k*2,l,mid,x,y,v);
updata2(k*2+1,mid+1,r,x,y,v);
sum[k]=(sum[k*2]%mod+sum[k*2+1]%mod)%mod;
return;
}
int q(int k,int l,int r,int x,int y){
if(r<x||l>y)return 0;
if(l>=x&&r<=y){
return sum[k]%mod;
}
down(k,l,r);
int mid=(l+r)/2,ans=0;
ans+=q(k*2,l,mid,x,y)%mod;
ans%=mod;
ans+=q(k*2+1,mid+1,r,x,y)%mod;
return ans%mod;
}
signed main(){
cin>>n>>m>>mod;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,n,1);
for(int i=1;i<=m;i++){
int c,x,y,k;
cin>>c;
if(c==1){
cin>>x>>y>>k;
updata2(1,1,n,x,y,k);//区间乘
}else if(c==2){
cin>>x>>y>>k;
updata1(1,1,n,x,y,k);//区间加
}else if(c==3){
cin>>x>>y;
cout<<(q(1,1,n,x,y)%mod)<<endl;//查询
}
}
return 0;
}