#include<iostream>
#include<cstdio>
using namespace std;
const int N=100010;
#define LL unsigned long long
int n,m;
LL M;
int f[N];
struct node{
LL value;
int lc,rc;
int xl,xr;
LL alz,mlz;
}pool[N*4];
int topl=1;
inline LL read(){
char kl=getchar();
int f=1;
while(kl>'9'||kl<'0'){if(kl=='-')f=-1;kl=getchar();};
LL ret=0;
while(kl>='0'&&kl<='9'){ret=ret*10+kl-'0';kl=getchar();}
return f*ret;
}
inline int gl(int x){
return pool[x].xr-pool[x].xl+1;
}
inline void pushup(int x){
node topx=pool[x];
pool[x].value=(pool[topx.lc].value+pool[topx.rc].value)%M;
return;
}
int build(int ll,int rr){
int sorin=topl;topl++;
pool[sorin]={0,0,0,ll,rr,0,1};
if(ll==rr){
pool[sorin].value=f[ll];
return sorin;
}
int mid=((ll+rr)>>1);
pool[sorin].lc=build(ll,mid);
pool[sorin].rc=build(mid+1,rr);
pushup(sorin);
return sorin;
}
inline void pushdownM(int x){
node topx=pool[x];
pool[topx.lc].value=(1ll*(pool[topx.lc].value%M)*(pool[x].mlz%M))%M;
pool[topx.rc].value=(1ll*(pool[topx.rc].value%M)*(pool[x].mlz%M))%M;
pool[topx.lc].value+=(1ll*(gl(topx.lc)%M)*(pool[x].alz%M))%M;
pool[topx.rc].value+=(1ll*(gl(topx.rc)%M)*(pool[x].alz%M))%M;
pool[topx.lc].value%=M;
pool[topx.rc].value%=M;
pool[topx.lc].alz=((((pool[topx.lc].alz%M)*(pool[x].mlz%M))%M)+pool[x].alz)%M;
pool[topx.rc].alz=((((pool[topx.rc].alz%M)*(pool[x].mlz%M))%M)+pool[x].alz)%M;
pool[topx.lc].mlz*=(pool[x].mlz%M);
pool[topx.rc].mlz*=(pool[x].mlz%M);
pool[topx.lc].mlz%=M;
pool[topx.rc].mlz%=M;
pool[x].alz=0;
pool[x].mlz=1;
return;
}
inline void pushdownA(int x){
node topx=pool[x];
pool[topx.lc].value+=(1ll*(gl(topx.lc)%M)*(pool[x].alz%M))%M;pool[topx.lc].value%=M;
pool[topx.rc].value+=(1ll*(gl(topx.rc)%M)*(pool[x].alz%M))%M;pool[topx.rc].value%=M;
pool[topx.lc].alz+=(pool[x].alz%M);pool[topx.lc].alz%=M;
pool[topx.rc].alz+=(pool[x].alz%M);pool[topx.rc].alz%=M;
pool[x].alz=0;
return;
}
inline void changeAdd(int x,int ll,int rr,int derta){
//if(x==0)return;
if(ll<=pool[x].xl&&pool[x].xr<=rr){
pool[x].value+=(1ll*derta*(gl(x)%M))%M;pool[x].value%=M;
pool[x].alz+=derta;pool[x].alz%=M;
return;
}
pushdownM(x);
if(pool[pool[x].lc].xr>=ll)changeAdd(pool[x].lc,ll,rr,derta);
if(pool[pool[x].rc].xl<=rr)changeAdd(pool[x].rc,ll,rr,derta);
pushup(x);
return;
}
inline void changeMul(int x,int ll,int rr,int derta){
//if(x==0)return;
if(ll<=pool[x].xl&&pool[x].xr<=rr){
pushdownA(x);
pool[x].value=((pool[x].value%M)*derta)%M;
pool[x].mlz*=derta;
pool[x].mlz%=M;
return;
}
pushdownM(x);
if(pool[pool[x].lc].xr>=ll)changeMul(pool[x].lc,ll,rr,derta);
if(pool[pool[x].rc].xl<=rr)changeMul(pool[x].rc,ll,rr,derta);
pushup(x);
return;
}
inline LL quir(int x,int ll,int rr){
LL ret=0;
//if(x==0)return 0;
if(ll<=pool[x].xl&&pool[x].xr<=rr){
return pool[x].value;
}
pushdownM(x);
if(pool[pool[x].lc].xr>=ll)ret+=quir(pool[x].lc,ll,rr);
ret%=M;
if(pool[pool[x].rc].xl<=rr)ret+=quir(pool[x].rc,ll,rr);
return ret%M;
}
int main(){
freopen("b.txt","r",stdin);
//freopen("b.ans","w",stdout);
n=read(),m=read(),M=read();
for(int i=1;i<=n;i++){
f[i]=read();
}
build(1,n);
for(int i=1;i<=m;i++){
int modes=read();
if(modes==1){
int ll=read(),rr=read(),d=read() ;
changeMul(1,ll,rr,(d%M));
}
else if(modes==2){
int ll=read(),rr=read(),d=read() ;
changeAdd(1,ll,rr,(d%M));
}else{
int ll=read(),rr=read();
printf("%lld\n",quir(1,ll,rr));
}
}
return 0;
}
能mod的都mod了,救救孩子吧