我又来了
我照着某一篇题解对了一遍感觉差不多啊,为什么样例都过不去啊,哪位神仙可以来救救我qwq
#include <iostream>//全文%p都是照着题解抄的,bdfs了一下同余定理感觉似懂非懂
#include <cstdio>
using namespace std;
#define ll long long
ll n,m,p,a[1000000],b,x,y,k;
struct gs
{
ll r,l,num,j,c=1;//j是加法懒标记,c是乘法懒标记
}shu[1000000];
void build(ll g,ll l,ll r)
{
shu[g].l=l;
shu[g].r=r;
shu[g].c=1;
if(l==r)
{
shu[g].num=a[l]%p;
return ;
}
ll mid=(r+l)/2;
build(g*2,l,mid);
build(g*2+1,mid+1,r);
shu[g].num=(shu[g*2].num+shu[g*2+1].num)%p;
}
void cd(ll g,ll c,ll j)//传递懒标记
{
shu[g].c=(shu[g].c*c)%p;
shu[g].j=(shu[g].j*c+j)%p;
shu[g].num=(shu[g].num*c+(j*(shu[g].r-shu[g].l+1))%p)%p;
}
void cf(ll l,ll r,ll num,ll g)//乘法
{
if(shu[g].l>=l&&shu[g].r<=r)
{
shu[g].j=(shu[g].j*num)%p;
shu[g].c=(shu[g].c*num)%p;
shu[g].num=(shu[g].num*num)%p;
return ;
}
cd(g*2,shu[g].c,shu[g].j);
cd(g*2+1,shu[g].c,shu[g].j);
shu[g].c=1;
shu[g].j=0;
ll mid=(shu[g].l+shu[g].r)/2;
if(l<=mid) cf(l,r,num,g*2);
if(r>mid) cf(l,r,num,g*2+1);
shu[g].num=(shu[g*2].num+shu[g*2+1].num)%p;
}
void jf(ll l,ll r,ll num,ll g)//加法
{
if(shu[g].l>=l&&shu[g].r<=r)
{
shu[g].j=(shu[g].j+num)%p;
shu[g].num=(shu[g].num+shu[g].j*(shu[g].r-shu[g].l+1))%p;
return ;
}
cd(g*2,shu[g].c,shu[g].j);
cd(g*2+1,shu[g].c,shu[g].j);
shu[g].j=0;
shu[g].c=1;
ll mid=(shu[g].l+shu[g].r)/2;
if(l<=mid) jf(l,r,num,g*2);
if(r>mid) jf(l,r,num,g*2+1);
shu[g].num=(shu[g*2].num+shu[g*2+1].num)%p;
}
long long count(ll l,ll r,ll g,ll ans)//计算区间和
{
if(shu[g].l>=l&&shu[g].r<=r) return shu[g].num;
cd(g*2,shu[g].c,shu[g].j);
cd(g*2+1,shu[g].c,shu[g].j);
shu[g].j=0;
shu[g].c=1;
ll mid=(shu[g].l+shu[g].r)/2;
if(l<=mid) ans=(ans+count(l,r,g*2,0))%p;
if(r>mid) ans=(ans+count(l,r,g*2+1,0))%p;
return ans;
}
int main()
{
scanf("%lld%lld%lld",&n,&m,&p);
for(ll i=1;i<=n;i++) scanf("%lld",&a[i]);
build(1,1,n);
for(ll i=1;i<=m;i++)
{
scanf("%lld",&b);
if(b==1)
{
scanf("%lld%lld%lld",&x,&y,&k);
cf(x,y,k,1);
}
if(b==2)
{
scanf("%lld%lld%lld",&x,&y,&k);
jf(x,y,k,1);
}
if(b==3)
{
scanf("%lld%lld",&x,&y);
printf("%lld\n",count(x,y,1,0));
}
}
return 0;
}