过了#1 #3 #4,问题应该就是在取模上,有没有dalao帮忙看一下:(
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
int n,m;
ll p;
ll a[500005];
struct node
{
ll sum;
int l,r;
int len()
{
return (r-l+1);
}
ll tag1,tag2;//1:乘法,2:加法
};
node t[2000005];
void pushup(int id)
{
t[id].sum=(((t[id*2].sum*1ll%p+t[id*2+1].sum*1ll%p))*1ll)%p;
return;
}
void build(int id,int l,int r)
{
t[id].l=l;
t[id].r=r;
t[id].tag1=1;
t[id].tag2=0;
if(l==r)
{
t[id].sum=a[l]%p;
return;
}
int mid=(l+r)/2;
build(id*2,l,mid);
build(id*2+1,mid+1,r);
pushup(id);
}
void savetag1(int id,ll w)
{
t[id].sum=((1ll*t[id].sum*1ll*w)%p)%p;
t[id].tag1=(1ll*t[id].tag1*w)%p;
t[id].tag2=(1ll*t[id].tag2*w)%p;
}
void savetag2(int id,ll w)
{
t[id].sum=(t[id].sum%p+t[id].len()*(ll)w*1ll%p)%p;
t[id].tag2=1ll*(t[id].tag2+w)%p;
}
void pushdown(int id)
{
if(t[id].tag1!=0)
{
savetag1(id*2,1ll*t[id].tag1);
savetag1(id*2+1,1ll*t[id].tag1);
t[id].tag1=1;
}
if(t[id].tag2!=0)
{
savetag2(id*2,t[id].tag2%p);
savetag2(id*2+1,t[id].tag2%p);
t[id].tag2=0;
}
return;
}
void update1(int id,int l,int r,int x,int y,ll w)//乘法
{
if(x<=l&&r<=y)
{
savetag1(id,w%p);
return;
}
pushdown(id);
int mid=(l+r)/2;
if(mid>=x)
{
update1(id*2,l,mid,x,y,w);
}
if(mid<y)
{
update1(id*2+1,mid+1,r,x,y,w);
}
pushup(id);
}
void update2(int id,int l,int r,int x,int y,ll w)
{
if(x<=l&&r<=y)
{
savetag2(id,w);
return;
}
pushdown(id);
int mid=(l+r)/2;
if(mid>=x)
{
update2(id*2,l,mid,x,y,w);
}
if(mid<y)
{
update2(id*2+1,mid+1,r,x,y,w);
}
pushup(id);
}
ll query(int id,int l,int r,int x,int y)
{
if(x<=l&&r<=y)
{
return t[id].sum%p;
}
pushdown(id);
int mid=(l+r)/2;
ll tot=0;
if(mid>=x)
{
tot=(tot+query(id*2,l,mid,x,y)*1ll)%p;
}
if(y>mid)
{
tot=(tot+query(id*2+1,mid+1,r,x,y)*1ll)%p;
}
return tot;
}
int main()
{
cin.tie(0)->ios::sync_with_stdio(0);
// freopen("xds.in","r",stdin);
// freopen("xds.out","w",stdout);
cin>>n>>m>>p;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
build(1,1,n);
int op;
ll t,g,c;
while(m--)
{
cin>>op;
if(op==1)
{
cin>>t>>g>>c;
update1(1,1,n,t,g,c);
}
if(op==2)
{
cin>>t>>g>>c;
update2(1,1,n,t,g,c);
}
if(op==3)
{
cin>>t>>g;
ll ans=(query(1,1,n,t,g)*1ll)%p;
cout<<((ans*1ll)%p+p)%p<<'\n';
}
}
return 0;
}