应该是Push down的原因,调好久没找到
#include<bits/stdc++.h>
#define MAXN 100001
#define ll long long
using namespace std;
ll tree[MAXN<<2],add_tag[MAXN<<2],mul_tag[MAXN<<2];
int a[MAXN];
int n,m,mod;
inline int ls(int p)
{
return p<<1;
}
inline int rs(int p)
{
return p<<1|1;
}
inline void push_up(int p)
{
tree[p]=(tree[ls(p)]+tree[rs(p)])%mod;
}
void build(int p,int l,int r)
{
if(l==r)
{
tree[p]=a[l]%mod;
return;
}
add_tag[p]=0;
mul_tag[p]=1;
int mid=(l+r)>>1;
build(ls(p),l,mid);
build(rs(p),mid+1,r);
push_up(p);
}
inline void push_down(int p,int l,int r)
{
int mid=(l+r)>>1;
tree[ls(p)]=(tree[ls(p)]*mul_tag[p]+(mid-l+1)*add_tag[p])%mod;
tree[rs(p)]=(tree[rs(p)]*mul_tag[p]+(r-mid)*add_tag[p])%mod;
mul_tag[ls(p)]=(mul_tag[p]*mul_tag[ls(p)])%mod;
mul_tag[rs(p)]=(mul_tag[p]*mul_tag[rs(p)])%mod;
add_tag[ls(p)]=(add_tag[ls(p)]*mul_tag[p]+add_tag[p])%mod;
add_tag[rs(p)]=(add_tag[rs(p)]*mul_tag[p]+add_tag[p])%mod;
add_tag[p]=0;
mul_tag[p]=1;
}
void mul_update(int p,int x,int y,int l,int r,ll k)
{
if(x<=l&&r<=y)
{
tree[p]=(tree[p]*k)%mod;
add_tag[p]=(add_tag[p]*k)%mod;
mul_tag[p]=(mul_tag[p]*k)%mod;
return;
}
int mid=(l+r)>>1;
push_down(p,l,r);
if(l<=mid) mul_update(ls(p),x,y,l,mid,k);
if(mid<r) mul_update(rs(p),x,y,mid+1,r,k);
push_up(p);
}
void add_update(int p,int x,int y,int l,int r,ll k)
{
if(x<=l&&r<=y)
{
add_tag[p]=(add_tag[p]+k)%mod;
tree[p]=(tree[p]+(r-l+1)*k)%mod;
return;
}
int mid=(l+r)>>1;
push_down(p,l,r);
if(l<=mid) add_update(ls(p),x,y,l,mid,k);
if(mid<r) add_update(rs(p),x,y,mid+1,r,k);
push_up(p);
}
ll query(int p,int x,int y,int l,int r)
{
if(x<=l&&r<=y) return tree[p];
ll res=0;
int mid=(l+r)>>1;
push_down(p,l,r);
if(x<=mid) res=(res+query(ls(p),x,y,l,mid))%mod;
if(y>mid) res=(res+query(rs(p),x,y,mid+1,r))%mod;
return res;
}
inline int read()
{
int x=0,f=1;
char c=getchar();
while(!isdigit(c))
{
if(c=='-') f=-1;
c=getchar();
}
while(isdigit(c))
{
x=(x<<1)+(x<<3)+c-48;
c=getchar();
}
return x*f;
}
int main()
{
n=read();m=read();mod=read();
for(int i=1;i<=n;i++) a[i]=read();
build(1,1,n);
for(int i=1;i<=m;i++)
{
int opt=read(),x,y,k;
switch(opt)
{
case 1:
x=read();y=read();k=read();
mul_update(1,x,y,1,n,(ll)k);
break;
case 2:
x=read();y=read();k=read();
add_update(1,x,y,1,n,(ll)k);
break;
case 3:
x=read();y=read();
printf("%lld\n",query(1,x,y,1,n));
break;
}
}
return 0;
}