#include <bits/stdc++.h>
using namespace std;
#define int long long
namespace SegmentTree
{
#define maxn 100002
int n,num[maxn],mod=571373;
struct node
{
int l,r,sum,add,mul;
} a[maxn<<2];
#define ls(k) (k<<1)
#define rs(k) (k<<1|1)
#define len(k) (a[k].l-a[k].r+1)
inline void update(int k)
{
a[k].sum=(a[ls(k)].sum+a[rs(k)].sum)%mod;
}
inline void pushdown(int k)
{
if(a[k].add==0&&a[k].mul==1)
return;
a[ls(k)].mul*=a[k].mul;
a[ls(k)].add*=a[k].mul;
a[ls(k)].add+=a[k].add;
a[ls(k)].sum=a[ls(k)].sum*a[k].mul+a[k].add*len(ls(k));
a[ls(k)].mul%=mod,a[ls(k)].add%=mod,a[ls(k)].sum%=mod;
a[rs(k)].mul*=a[k].mul;
a[rs(k)].add*=a[k].mul;
a[rs(k)].add+=a[k].add;
a[rs(k)].sum=a[rs(k)].sum*a[k].mul+a[k].add*len(rs(k));
a[rs(k)].mul%=mod,a[rs(k)].add%=mod,a[rs(k)].sum%=mod;
a[k].mul=1;
a[k].add=0;
}
void build(int k,int l,int r)
{
a[k].mul=1;
a[k].add=0;
a[k].l=l,a[k].r=r;
if(l==r)
{
a[k].sum=num[l]%mod;
return;
}
int mid=(l+r)>>1;
build(ls(k),l,mid);
build(rs(k),mid+1,r);
update(k);
}
int query(int k,int l,int r)
{
pushdown(k);
if(a[k].l==l&&a[k].r==r)
return a[k].sum%mod;
int mid=(a[k].l+a[k].r)>>1;
if(r<=mid)
return query(ls(k),l,r)%mod;
else if(l>mid)
return query(rs(k),l,r)%mod;
else
return (query(ls(k),l,mid)+query(rs(k),mid+1,r))%mod;
}
void editSum(int k,int l,int r,int v)
{
pushdown(k);
if(a[k].l==l&&a[k].r==r)
{
a[k].sum+=len(k)*v;
a[k].add+=v;
a[k].sum%=mod,a[k].add%=mod;
return;
}
int mid=(a[k].l+a[k].r)>>1;
if(r<=mid)
editSum(ls(k),l,r,v);
else if(l>mid)
editSum(rs(k),l,r,v);
else
editSum(ls(k),l,mid,v),editSum(rs(k),mid+1,r,v);
update(k);
}
void editMul(int k,int l,int r,int v)
{
pushdown(k);
if(a[k].l==l&&a[k].r==r)
{
a[k].mul*=v;
a[k].add*=v;
a[k].sum*=v;
a[k].mul%=mod,a[k].add%=mod,a[k].sum%=mod;
return;
}
int mid=(a[k].l+a[k].r)>>1;
if(r<=mid)
editMul(ls(k),l,r,v);
else if(l>mid)
editMul(rs(k),l,r,v);
else
editMul(ls(k),l,mid,v),editMul(rs(k),mid+1,r,v);
update(k);
}
}
using namespace SegmentTree;
int m,op,l,r,x;
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin >> n >> m >> mod;
for(int i=1;i<=n;++i)
cin >> num[i];
build(1,1,n);
while(m--)
{
cin >> op >> l >> r;
if(op==3)
cout << query(1,l,r)%mod << endl;
else if(op==1)
{
cin >> x;
editMul(1,l,r,x);
}
else if(op==2)
{
cin >> x;
editSum(1,l,r,x);
}
}
return 0;
}
萌新刚学线段树2 qwq