经过调试,乘法的部分写炸了,但是不知道为什么。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define int ll
const int N=5e5+5;
ll block[N],id[N],a[N],tag1[N],tag2[N];
int len;
int n,m;
inline int qpow(int a,int b)
{
int ans=1;
for(;b;b>>=1,a=a*a%m) if(b&1) ans=ans*a%m;
return ans;
}
void build()
{
//清空全部块
memset(block,0,sizeof block);
memset(tag2,1,sizeof tag2);
fill(tag2,tag2+N,1);
len=1;
for(int i=1; i<=n; i++)
{
id[i]=(i-1)/len+1;
block[id[i]]+=a[i];
block[id[i]]%=m;
}
}
void update1(int l,int r,ll w)
{
int p1=id[l],p2=id[r];
if(p1==p2)
{
for(int i=l; i<=r; i++)
{
a[i]*=w;
a[i]%=m;
block[p1]*=w;
block[p1]%=m;
}
return;
}
for(int i=l; i<=p1*len; i++)
{
a[i]*=w;
a[i]%=m;
block[p1]*=w;
block[p1]%=m;
}
for(int i=(p2-1)*len+1; i<=min(r,n); i++)
{
a[i]*=w;
a[i]%=m;
block[p2]*=w;
block[p2]%=m;
}
for(int i=p1+1; i<=p2-1; i++)
{
block[i]*=1LL*len*w;
block[i]%=m;
tag2[i]*=w;
tag2[i]%=m;
}
return;
}
void update2(int l,int r,ll w)
{
int p1=id[l],p2=id[r];
if(p1==p2)
{
for(int i=l; i<=r; i++)
{
a[i]+=w;
a[i]%=m;
block[p1]+=w;
block[p1]%=m;
}
return;
}
for(int i=l; i<=p1*len; i++)
{
a[i]+=w;
a[i]%=m;
block[p1]+=w;
block[p1]%=m;
}
for(int i=(p2-1)*len+1; i<=min(r,n); i++)
{
a[i]+=w;
a[i]%=m;
block[p2]+=w;
block[p2]%=m;
}
for(int i=p1+1; i<=p2-1; i++)
{
block[i]+=1LL*len*w;
block[i]%=m;
tag1[i]+=w;
tag1[i]%=m;
}
return;
}
void pushdown(int k)
{
if(tag1[k])
{
for(int i=(k-1)*len+1; i<=k*len; i++)
{
a[i]+=tag1[k];
a[i]%=m;
}
tag1[k]=0;
}
if(tag2[k]!=1)
{
for(int i=(k-1)*len+1;i<=k*len;i++)
{
a[i]*=tag2[k];
a[i]%=m;
}
tag2[k]=1;
}
return;
}
ll query(int l,int r)
{
int p1=id[l],p2=id[r];
ll ans=0;
pushdown(p1);
pushdown(p2);
if(p1==p2)
{
for(int i=l; i<=r; i++)
{
ans+=a[i];
ans%=m;
}
return ans;
}
for(int i=l; i<=p1*len; i++) ans+=a[i],ans%=m;
for(int i=(p2-1)*len+1; i<=min(r,n); i++)
{
ans+=a[i];
ans%=m;
}
for(int i=p1+1; i<=p2-1; i++) ans+=block[i],ans%=m;
return ans;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int q;
cin>>n>>q>>m;
for(int i=1; i<=n; i++) cin>>a[i];
build();
while(q--)
{
int op;
int l,r;
cin>>op>>l>>r;
if(op==1)
{
int k;
cin>>k;
update1(l,r,k);
}
else if(op==2)
{
int k;
cin>>k;
update2(l,r,k);
}
else
{
cout<<query(l,r)%m<<endl;
}
}
return 0;
}
验证码 666f 祭。