#include<iostream>
using namespace std;
const int N = 1e5+10;
struct Node{
long long l,r,sum,tag_add,tag_mul;
}tr[4*N];
int n,m;
long long p;
long long a[N];
long long aa,x,y;
long long k;
void push_up(int u)
{
tr[u].sum=((tr[u<<1].sum+tr[u<<1|1].sum)%p+p)%p;
}
void push_down(int u)
{
if(tr[u].tag_add==0&&tr[u].tag_mul==1)return;
int l=tr[u].l,r=tr[u].r;
int t1=tr[u].tag_add;
int t2=tr[u].tag_mul;
tr[u].tag_add=0;
tr[u].tag_mul=1;
int mid=(l+r)/2;
tr[u<<1].tag_add=((tr[u<<1].tag_add*t2%p+t1)%p+p)%p;
tr[u<<1|1].tag_add=((tr[u<<1|1].tag_add*t2%p+t1)%p+p)%p;
tr[u<<1].tag_mul=(tr[u<<1].tag_mul*t2%p+p)%p;
tr[u<<1|1].tag_mul=(tr[u<<1|1].tag_mul*t2%p+p)%p;
tr[u<<1].sum=(((tr[u<<1].sum*t2)%p+t1*(mid-l+1)%p)%p+p)%p;
tr[u<<1|1].sum=(((tr[u<<1|1].sum*t2)%p+t1*(r-mid)%p)%p+p)%p;
}
void build(int u,long l,long long r)
{
if(l==r)
{
tr[u]={l,r,a[l],0,1};
return ;
}
tr[u]={l,r};
tr[u].tag_mul=1;
int mid=(l+r)>>1;
build(u<<1,l,mid),build(u<<1|1,mid+1,r);
push_up(u);
}
long long query(int u,long long l,long long r)
{
if(tr[u].l>=l&&tr[u].r<=r)return tr[u].sum;
push_down(u);
long long sum=0;
int mid=((tr[u].l+tr[u].r)%p)/2;
if(mid>=l)sum=((sum+query(u<<1,l,r))%p+p)%p;
if(mid<r)sum=((sum+query(u<<1|1,l,r))%p+p)%p;
return sum%p;
}
void modify_add(int u,long long l,long long r,long long k)
{
if(tr[u].l>=l&&tr[u].r<=r)
{
tr[u].sum=((tr[u].sum+k*(tr[u].r-tr[u].l+1)%p)%p+p)%p;
tr[u].tag_add=((tr[u].tag_add+k)%p+p)%p;
return;
}
push_down(u);
int mid=(tr[u].l+tr[u].r)/2;
if(mid>=l)modify_add(u<<1,l,r,k);
if(mid<r)modify_add(u<<1|1,l,r,k);
push_up(u);
}
void modify_mul(int u,long long l,long long r,long long k)
{
if(tr[u].l>=l&&tr[u].r<=r)
{
if(tr[u].tag_add)tr[u].tag_add=((tr[u].tag_add*k)%p+p)%p;
tr[u].sum=(k*tr[u].sum%p+p)%p;
tr[u].tag_mul=((tr[u].tag_mul*k)%p+p)%p;
return;
}
push_down(u);
int mid=(tr[u].l+tr[u].r)/2;
if(mid>=l)modify_mul(u<<1,l,r,k);
if(mid<r)modify_mul(u<<1|1,l,r,k);
push_up(u);
}
int main()
{
scanf("%d%d%lld",&n,&m,&p);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
build(1,1,n);
for(int i=1;i<=m;i++)
{
scanf("%lld",&aa);
if(aa==1)
{
scanf("%lld%lld%lld",&x,&y,&k);
modify_mul(1,x,y,k);
}
else if(aa==2)
{
scanf("%lld%lld%lld",&x,&y,&k);
modify_add(1,x,y,k);
}
else if(aa==3)
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",query(1,x,y));
}
}
return 0;
}
改了半天了,呜呜呜~