代码如下
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<iomanip>
#include<cstdio>
#include<math.h>
#include<string>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define ll long long int
#define maxn 100100
#define ls rt<<1
#define rs rt<<1|1
using namespace std;
int n,m,p;
ll ans;
struct node{
int b,e;
ll sum,mu,su;
}tree[maxn<<2];
void create(int rt,int l,int r)
{
tree[rt].b=l;
tree[rt].e=r;
tree[rt].mu=1;
if(l==r)
{
scanf("%lld",&tree[rt].sum);
tree[rt].sum%=p;
return;
}
int mid=(l+r)>>1;
create(ls,l,mid);
create(rs,mid+1,r);
tree[rt].sum=tree[ls].sum+tree[rs].sum;
tree[rt].sum%=p;
}
void pluss(int rt,int s,int t)
{
tree[rt].sum=(tree[rt].sum*s%p+t*(tree[rt].e-tree[rt].b+1)%p)%p;
tree[rt].mu=(tree[rt].mu*s)%p;
tree[rt].su=(tree[rt].su*s+t)%p;
}
void pushed(int rt)
{
pluss(ls,tree[rt].mu,tree[rt].su);
pluss(rs,tree[rt].mu,tree[rt].su);
tree[rt].mu=1;
tree[rt].su=0;
}
void pushup(int rt)
{
tree[rt].sum=tree[ls].sum+tree[rs].sum;
tree[rt].sum%=p;
}
//乘法
void updatex(int rt,int l,int r,int k)
{
if(l<=tree[rt].b&&tree[rt].e<=r)
{
pluss(rt,k,0);
return;
}
if(tree[rt].e<l||tree[rt].b>r)
{
return;
}
if(tree[rt].mu!=1||tree[rt].su)
{
pushed(rt);
}
updatex(ls,l,r,k);
updatex(rs,l,r,k);
pushup(rt);
}
//加法
void updatey(int rt,int l,int r,int k)
{
if(l<=tree[rt].b&&tree[rt].e<=r)
{
pluss(rt,1,k);
return;
}
if(tree[rt].e<l||tree[rt].b>r)
{
return;
}
if(tree[rt].mu!=1||tree[rt].su)
{
pushed(rt);
}
updatey(ls,l,r,k);
updatey(rs,l,r,k);
pushup(rt);
}
//搜索
void dfs(int rt,int l,int r)
{
if(l<=tree[rt].b&&tree[rt].e<=r)
{
ans+=tree[rt].sum;
ans%=p;
return;
}
if(tree[rt].e<l||tree[rt].b>r)
{
return;
}
if(tree[rt].mu!=1||tree[rt].su)
{
pushed(rt);
}
dfs(ls,l,r);
dfs(rs,l,r);
pushup(rt);
}
int main()
{
scanf("%d%d%d",&n,&m,&p);
create(1,1,n);
for(int i=1;i<=m;i++)
{
int a,x,y,k;
scanf("%d",&a);
if(a==1)
{
scanf("%d%d%d",&x,&y,&k);
updatex(1,x,y,k);
continue;
}
if(a==2)
{
scanf("%d%d%d",&x,&y,&k);
updatey(1,x,y,k);
continue;
}
if(a==3)
{
ans=0;
scanf("%d%d",&x,&y);
dfs(1,x,y);
printf("%lld\n",ans%p);
}
}
return 0;
}
/*
```cpp
调了三天了今天第四天实在蚌埠住了