题目
思路
其实我们从这里就可以完成操作2,3,重点就在操作1.
对于区间乘,我们发现只有一个lazy是不够的,我们还需要一个lazy2,用来处理乘法,详见代码(汉语拼音函数名见谅)
code:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
long long tree[800008],lazy[800008],n,f,a[400004],x,L,R,p,lazycf[800008];
void jianshu(long long l,long long r,long long id)
{
lazy[id]=0,lazycf[id]=1;
if (l==r)
{
tree[id]=a[l]%p;
return;
}
jianshu(l,(l+r)>>1,id*2);
jianshu(((l+r)>>1)+1,r,id*2+1);
tree[id]=(tree[id*2]+tree[id*2+1])%p;
return;
}
void down(long long l,long long r,long long id)
{
long long mid=(l+r)>>1;
lazy[id*2]=(lazy[id*2]*lazycf[id]+lazy[id])%p;
lazy[id*2+1]=(lazy[id*2+1]*lazycf[id]+lazy[id])%p;
lazycf[id*2]=(lazycf[id*2]*lazycf[id])%p;
lazycf[id*2+1]=(lazycf[id*2+1]*lazycf[id])%p;
tree[id*2]=(tree[id*2]*lazycf[id]+lazy[id]*(mid-l+1))%p;
tree[id*2+1]=(tree[id*2+1]*lazycf[id]+lazy[id]*(r-mid))%p;
lazy[id]=0;
lazycf[id]=1;
return;
}
void qjgxjiafa(long long l,long long r,long long id)
{
if (l>=L&&R>=r)
{
tree[id]=(tree[id]+x*(r-l+1))%p;
lazy[id]=(lazy[id]+x)%p;
return;
}
down(l,r,id);
long long mid=(l+r)>>1;
if (L<=mid) qjgxjiafa(l,mid,id*2);
if (R>mid) qjgxjiafa(mid+1,r,id*2+1);
tree[id]=(tree[id*2]+tree[id*2+1])%p;
return;
}
void qjgxchenfa(long long l,long long r,long long id)
{
if (l>=L&&R>=r)
{
tree[id]=(tree[id]*x)%p;
lazy[id]=(lazy[id]*x)%p;
lazycf[id]=(lazycf[id]*x)%p;
return;
}
down(l,r,id);
long long mid=(l+r)>>1;
if (L<=mid) qjgxchenfa(l,mid,id*2);
if (R>mid) qjgxchenfa(mid+1,r,id*2+1);
tree[id]=(tree[id*2]+tree[id*2+1])%p;
return;
}
long long qjcx(long long l,long long r,long long id)
{
if (l>=L&&R>=r)
{
return tree[id];
}
down(l,r,id);
long long mid=(l+r)>>1,ans=0;
if (L<=mid) ans=(ans+qjcx(l,mid,id*2))%p;
if (R>mid) ans=(ans+qjcx(mid+1,r,id*2+1))%p;
return ans;
}
long long u;
int main()
{
cin>>n>>f>>p;
for (long long i=1;i<=n;i++) cin>>a[i];
jianshu(1,n,1);
for (long long i=1;i<=f;i++)
{
scanf("%lld",&u);
if (u==2)
{
scanf("%lld%lld%lld",&L,&R,&x);
qjgxjiafa(1,n,1);
}
if (u==3)
{
scanf("%lld%lld",&L,&R);
printf("%lld\n",qjcx(1,n,1));
}
if (u==1)
{
scanf("%lld%lld%lld",&L,&R,&x);
qjgxchenfa(1,n,1);
}
}
return 0;
}