自己造了十个刁钻的小样例过了,一提交,只见眼前一红
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int maxn=114514;
int n,m,p;
int a[maxn];
struct Tree{
int left,right;
int data,lazyj,lazyc;
}tree[maxn*4];
void build(int l,int r,int i)
{
tree[i].lazyj=0;
tree[i].lazyc=1;
tree[i].left=l;
tree[i].right=r;
if(l==r)
{
tree[i].data=a[l];
return;
}
int mid=(l+r)>>1;
build(l,mid,i<<1);
build(mid+1,r,i<<1|1);
tree[i].data=tree[i<<1].data+tree[i<<1|1].data;
}
void pushdown(int i)
{
if(tree[i].lazyc!=1)
{
tree[i<<1].lazyc=tree[i<<1].lazyc*tree[i].lazyc;
tree[i<<1|1].lazyc=tree[i<<1|1].lazyc*tree[i].lazyc;
tree[i<<1].data=(tree[i<<1].data*tree[i].lazyc)%p;
tree[i<<1|1].data=(tree[i<<1|1].data*tree[i].lazyc)%p;
tree[i].lazyc=1;
}
if(tree[i].lazyj!=0)
{
tree[i<<1].lazyj=tree[i<<1].lazyj+tree[i].lazyj;
tree[i<<1|1].lazyj=tree[i<<1|1].lazyj+tree[i].lazyj;
tree[i<<1].data=(tree[i<<1].data+tree[i].lazyj*(tree[i<<1].right-tree[i<<1].left+1))%p;
tree[i<<1|1].data=(tree[i<<1|1].data+tree[i].lazyj*(tree[i<<1|1].right-tree[i<<1|1].left+1))%p;
tree[i].lazyj=0;
}
}
void modify(int l,int r,int k,int i,char f)
{
if(l<=tree[i].left&&tree[i].right<=r)
{
if(f=='+')
{
tree[i].data=(tree[i].data+k*(tree[i].right-tree[i].left+1))%p;
tree[i].lazyj=tree[i].lazyj+k;
}
else
{
tree[i].data=(tree[i].data*k)%p;
tree[i].lazyc=tree[i].lazyc*k;
}
return;
}
pushdown(i);
if(l<=tree[i<<1].right)modify(l,r,k,i<<1,f);
if(tree[i<<1|1].left<=r)modify(l,r,k,i<<1|1,f);
tree[i].data=tree[i<<1].data+tree[i<<1|1].data;
}
int query(int l,int r,int i)
{
int res=0;
if(l<=tree[i].left&&tree[i].right<=r)
return tree[i].data%p;
pushdown(i);
if(l<=tree[i<<1].right)res=res+query(l,r,i<<1);
if(tree[i<<1|1].left<=r)res=res+query(l,r,i<<1|1);
return res%p;
}
signed main(){
int i,j,op,x,y,k;
cin>>n>>m>>p;
for(i=1;i<=n;i++)
cin>>a[i];
build(1,n,1);
while(m--)
{
cin>>op>>x>>y;
if(op==1)
{
cin>>k;
modify(x,y,k,1,'*');
}
if(op==2)
{
cin>>k;
modify(x,y,k,1,'+');
}
if(op==3)
cout<<query(x,y,1)<<endl;
}
return 0;
}