WA #1 #3 #4
#include <iostream>
#include <cstdio>
#include <queue>
#define int long long
using namespace std;
int tree[400001]={};
int tagc[400001]={};//乘积的tag
int tagh[400001]={};//和的tag
int nsum[400001]={};
int mo;
int left(int a)
{
return a<<1;
}
int right(int a)
{
return a<<1|1;
}
void push(int p)
{
tree[p]=(tree[left(p)]+tree[right(p)])%mo;
}
//建树
void build(int p,int l,int r)
{
if(r==l)
{
tree[p]=nsum[r]%mo;
return;
}
int kkk=(r+l)>>1;
build(left(p),l,kkk);
build(right(p),kkk+1,r);
push(p);
}
//下传,k1是父节点的和tag,k2是积tag
void f(int p,int l,int r,int k1,int k2)
{
tree[p]=tree[p]*k2%mo+k1*(r-l+1)%mo;
tree[p]%=mo;
tagc[p]=tagc[p]*k2%mo;
tagh[p]=tagh[p]*k2%mo+k1%mo;
tagh[p]%=mo;
tagc[p]%=mo;
}
void pushd(int p,int l,int r)
{
int kkk=(l+r)>>1;
f(left(p),l,kkk,tagh[p],tagc[p]);
f(right(p),kkk+1,r,tagh[p],tagc[p]);
tagh[p]=0;
tagc[p]=1;
}
//乘
void update1(int ll,int rr,int p,int l,int r,int num)
{
if(rr<l||ll>r)
return;
if(ll<=l&&rr>=r)
{
tree[p]*=num;
tree[p]%=mo;
tagc[p]*=num;
tagc[p]%=mo;
tagh[p]*=num;
tagh[p]%=mo;
return;
}
pushd(p,l,r);
int kkk=(l+r)>>1;
if(ll<=kkk)
update1(ll,rr,left(p),l,kkk,num);
if(rr>=kkk+1)
update1(ll,rr,right(p),kkk+1,r,num);
push(p);
return;
}
//加
void update2(int ll,int rr,int p,int l,int r,int num)
{
if(rr<l||ll>r)
return;
if(ll<=l&&rr>=r)
{
tree[p]+=num*(r-l+1)%mo;
tree[p]%=mo;
tagh[p]+=num;
tagh[p]%=mo;
return;
}
pushd(p,l,r);
int kkk=(l+r)>>1;
if(ll<=kkk)
update2(ll,rr,left(p),l,kkk,num);
if(rr>=kkk+1)
update2(ll,rr,right(p),kkk+1,r,num);
push(p);
return;
}
//取结果
int ans(int ll,int rr,int l,int r,int p)
{
if(rr<l||ll>r)
return 0;
int an=0;
if(ll<=l&&rr>=r)
return tree[p]%mo;
int kkk=(l+r)>>1;
pushd(p,l,r);
if(ll<=kkk)
an+=ans(ll,rr,l,kkk,left(p))%mo;
if(rr>=kkk+1)
an+=ans(ll,rr,kkk+1,r,right(p))%mo;
return an%mo;
}
#undef int
int main()
{
#define int long long
int n,m;
scanf("%lld %lld %lld",&n,&m,&mo);
for(int i=1;i<=n;i++)
{
scanf("%lld",&nsum[i]);
tagc[i]=1;
tagh[i]=0;
}
build(1,1,n);
for(int i=1;i<=m;i++)
{
int meiy;
scanf("%lld",&meiy);
if(meiy==1)
{
int aa,bb,cc;
scanf("%lld %lld %lld",&aa,&bb,&cc);
update1(aa,bb,1,1,n,cc);
}
if(meiy==2)
{
int aa,bb,cc;
scanf("%lld %lld %lld",&aa,&bb,&cc);
update2(aa,bb,1,1,n,cc);
}
if(meiy==3)
{
int aa,bb;
scanf("%lld %lld",&aa,&bb);
printf("%lld\n",ans(aa,bb,1,n,1)%mo);
}
}
return 0;
}