#include<bits/stdc++.h>
using namespace std;
const int maxn=114514;
struct node
{
int l,r;
int pri;
int sz;
long long val,sum,plu,tms;
#define l(x) tree[x].l
#define r(x) tree[x].r
#define p(x) tree[x].pri
#define sz(x) tree[x].sz
#define v(x) tree[x].val
#define su(x) tree[x].sum
#define pl(x) tree[x].plu
#define tm(x) tree[x].tms
}tree[maxn];
long long mod;
int rt,cnt,x,y,z;
inline int newnode(long long val)
{
v(++cnt)=val;
p(cnt)=rand();
sz(cnt)=1;
su(cnt)=val;
pl(cnt)=0;
tm(cnt)=1;
return cnt;
}
inline void update(int x)
{
sz(x)=sz(l(x))+sz(r(x))+1;
su(x)=su(l(x))+su(r(x))+v(x);
su(x)%=mod;
}
inline void qumo(int x)
{
v(x)%=mod;
pl(x)%=mod;
su(x)%=mod;
tm(x)%=mod;
}
inline void add(int x,long long val)
{
val%=mod;
v(x)+=val;
pl(x)+=val;
su(x)+=val*sz(x);
qumo(x);
}
inline void times(int x,long long val)
{
val%=mod;
v(x)*=val;
tm(x)*=val;
pl(x)*=val;
su(x)*=val;
qumo(x);
}
inline void pushdown(int x)
{
times(l(x),tm(x));
times(r(x),tm(x));
tm(x)=1;
add(l(x),pl(x));
add(r(x),pl(x));
pl(x)=0;
}
void split(int now,int siz,int &x,int &y)
{
if(!now) x=y=0;
else
{
pushdown(now);
if(sz(l(now))<siz)
{
x=now;
split(r(now),siz-sz(l(now))-1,r(now),y);
}
else
{
y=now;
split(l(now),siz,x,l(now));
}
update(now);
}
}
int merge1(int x,int y)
{
if(!x||!y) return x+y;
if(p(x)<p(y))
{
pushdown(x);
r(x)=merge1(r(x),y);
update(x);
return x;
}
else
{
pushdown(y);
l(y)=merge1(x,l(y));
update(y);
return y;
}
}
int main()
{
srand(time(0)*114514);
int n,m;
scanf("%d %d %lld",&n,&m,&mod);
for(int i=1;i<=n;i++)
{
int a;
scanf("%d",&a);
rt=merge1(rt,newnode(a));
}
//scanf("%d",&m);
for(int i=1;i<=m;i++)
{
int op,l,r;
scanf("%d %d %d",&op,&l,&r);
if(op==1)
{
int k;scanf("%d",&k);
split(rt,l-1,x,y);
split(y,r-l+1,y,z);
times(y,k);
rt=merge1(x,merge1(y,z));
}
if(op==2)
{
int k;scanf("%d",&k);
split(rt,l-1,x,y);
split(y,r-l+1,y,z);
add(y,k);
rt=merge1(x,merge1(y,z));
}
if(op==3)
{
split(rt,l-1,x,y);
split(y,r-l+1,y,z);
cout<<su(y)%mod<<endl;
rt=merge1(x,merge1(y,z));
}
}
return 0;
}
是不是luogu卡平衡树