#include<bits/stdc++.h>
#define int long long
using namespace std;
struct ccc{
int l,r,laz,pre,ta;
}tree[100000*4+100];
int a[1000000],p;
void build(int i,int le,int ri){
tree[i].l=le,tree[i].r=ri,tree[i].ta=1;
if(le==ri){
tree[i].pre=a[le];
return ;
}
int mid=(le+ri)>>1;
build(i*2,le,mid);
build(i*2+1,mid+1,ri);
tree[i].pre=(tree[i*2].pre+tree[i*2+1].pre);
}
void tag(int i){
tree[i*2].pre=(tree[i].ta*tree[i*2].pre+tree[i].laz*(tree[i*2].r-tree[i*2].l+1))%p;
tree[i*2+1].pre=(tree[i].ta*tree[i*2+1].pre+tree[i].laz*(tree[i*2+1].r-tree[i*2+1].l+1))%p;
tree[i*2].laz=(tree[i].ta*tree[i*2].laz+tree[i].laz)%p;
tree[i*2+1].laz=(tree[i].ta*tree[i*2+1].laz+tree[i].laz)%p;
tree[i*2].ta*=tree[i].ta%p;
tree[i*2+1].ta*=tree[i].ta%p;
tree[i].laz=0,tree[i].ta=1;
}
void change_mu(int i,int x,int y,int z){
if(x<=tree[i].l&&y>=tree[i].r){
tree[i].laz=tree[i].laz%p*z%p;
tree[i].ta=tree[i].ta%p*z%p;
tree[i].pre=tree[i].pre%p*z%p;
return ;
}
tag(i);
int mid=(tree[i].l+tree[i].r)>>1;
if(x<=mid) change_mu(i*2,x,y,z);
if(y>mid) change_mu(i*2+1,x,y,z);
tree[i].pre=(tree[i*2].pre+tree[i*2+1].pre);
}
void change_add(int i,int x,int y,int z){
if(x<=tree[i].l&&y>=tree[i].r){
tree[i].pre=(tree[i].pre+z*(tree[i].r-tree[i].l+1))%p;
tree[i].laz=(tree[i].laz+z)%p;
return ;
}
tag(i);
int mid=(tree[i].l+tree[i].r)>>1;
if(x<=mid) change_add(i*2,x,y,z);
if(y>mid) change_add(i*2+1,x,y,z);
tree[i].pre=(tree[i*2].pre+tree[i*2+1].pre)%p;
}
int get(int i,int x,int y){
int ans=0;
if(x<=tree[i].l&&y>=tree[i].r){
return tree[i].pre;
}
tag(i);
int mid=(tree[i].l+tree[i].r)>>1;
if(x<=mid) ans=(ans+get(i*2,x,y))%p;
if(y>mid) ans=(ans+get(i*2+1,x,y))%p;
return ans;
}
signed main(){
int n,m;
cin>>n>>m>>p;
for(int i=1;i<=n;i++)cin>>a[i];
build(1,1,n);
for(int i=1;i<=m;i++){
int opt;
cin>>opt;
if(opt==1){
int x,y,z;
cin>>x>>y>>z;
change_mu(1,x,y,z);
}
else if(opt==2){
int x,y,z;
cin>>x>>y>>z;
change_add(1,x,y,z);
}
else{
int x,y;
cin>>x>>y;
cout<<get(1,x,y)%p<<endl;
}
}
return 0;
}
记录