#2,9,10第一个输出有问题,努力检查了很久都没调好。模p大概也全加了一遍。
提前谢谢大佬帮助。
#include<iostream>
#include<cstdio>
using namespace std;
typedef long long s64;
int n,m;
s64 p;
s64 value[100004];
s64 add[800009];
s64 mult[800009];
s64 init[100004];
void build(int left,int right,int root)
{
mult[root]=1;
add[root]=0;
if(left==right)
{
value[root]=init[left]%p;
return;
}
int mid=(left+right)>>1;
build(left,mid,root<<1);
build(mid+1,right,(root<<1)|1);
value[root]=(value[root<<1]+value[(root<<1)|1])%p;
}
void pushdown(int root,int left,int right)
{
if(mult[root]!=1||add[root]!=0)
{
int lchild=root<<1,rchild=(root<<1)|1;
int mid=(left+right)>>1;
mult[lchild]=(mult[lchild]*mult[root])%p;
add[lchild]=((add[lchild]*mult[root])%p+add[root])%p;
value[lchild]=((value[lchild]*mult[root])%p+add[root]*(mid-left+1)%p)%p;
mult[rchild]=(mult[rchild]*mult[root])%p;
add[rchild]=((add[rchild]*mult[root])%p+add[root])%p;
value[rchild]=((value[rchild]*mult[root])%p+add[root]*(right-mid)%p)%p;
mult[root]=1;add[root]=0;
}
}
void Mult(int lgoal,int rgoal,s64 k,int l
now,int rnow,int root)
{
pushdown(root,lnow,rnow);
if(lgoal<=lnow&&rnow<=rgoal)
{
mult[root]=k;add[root]=(add[root]*k)%p;
value[root]=(value[root]*k)%p;
return;
}
int lc=root<<1,rc=(root<<1)|1,mid=(lnow+rnow)>>1;
if(lgoal<=mid) Mult(lgoal,rgoal,k,lnow,mid,lc);
if(mid<rgoal) Mult(lgoal,rgoal,k,mid+1,rnow,rc);
value[root]=(value[lc]+value[rc])%p;
}
void Add(int lgoal,int rgoal,s64 k,int lnow,int rnow,int root)
{
pushdown(root,lnow,rnow);
if(lgoal<=lnow&&rnow<=rgoal)
{
add[root]=(add[root]+k)%p;
value[root]=(value[root]+k*(rnow-lnow+1)%p)%p;
return;
}
int lc=root<<1,rc=(root<<1)|1,mid=(lnow+rnow)>>1;
if(lgoal<=mid) Add(lgoal,rgoal,k,lnow,mid,lc);
if(mid<rgoal) Add(lgoal,rgoal,k,mid+1,rnow,rc);
value[root]=(value[lc]+value[rc])%p;
}
s64 Getsum(int lgoal,int rgoal,int lnow,int rnow,int root)
{
s64 sum=0;
pushdown(root,lnow,rnow);
if(lgoal<=lnow&&rnow<=rgoal)
{
sum=value[root];
return sum%p;
}
int lc=root<<1,rc=(root<<1)|1,mid=(lnow+rnow)>>1;
if(lgoal<=mid) sum+=Getsum(lgoal,rgoal,lnow,mid,lc);
if(mid<rgoal) sum+=Getsum(lgoal,rgoal,mid+1,rnow,rc);
return sum%p;
}
int main()
{
cin>>n>>m>>p;
for(int i=1;i<=n;i++) cin>>init[i];
build(1,n,1);;
int op,x,y;
s64 k;
while(m--)
{
cin>>op;
if(op==1)
{
cin>>x>>y>>k;
Mult(x,y,k,1,n,1);
}
else if(op==2)
{
cin>>x>>y>>k;
Add(x,y,k,1,n,1);
}
else if(op==3)
{
cin>>x>>y;
cout<<Getsum(x,y,1,n,1)%p<<endl;
}
}
return 0;
}