#include<bits/stdc++.h>
using namespace std;
struct node
{
long long l,r,add,add2,pre;
}t[200014];
long long c[100004];
long long n,m,mod;
void build(long long x,long long a,long long b)
{
t[x].l=a;t[x].r=b;t[x].add2=1;
if(a==b)
{
t[x].pre=c[a]%mod;
return ;
}
long long mid=a+b>>1;
build(x*2,a,mid);
build(x*2+1,mid+1,b);
t[x].pre=(t[x*2].pre+t[x*2+1].pre)%mod;
return ;
}
void spread(long long x)
{
t[x*2].pre=(t[x].add2*t[x*2].pre)%mod;
t[x*2+1].pre=(t[x].add2*t[x*2+1].pre)%mod;
t[x*2].pre=(t[x*2].pre+t[x].add*(t[x*2].r-t[x*2].l+1))%mod;
t[x*2+1].pre=(t[x*2+1].pre+t[x].add*(t[x*2+1].r-t[x*2+1].l+1))%mod;
t[x*2].add2=(t[x*2].add2*t[x].add2)%mod;
t[x*2+1].add2=(t[x*2+1].add2*t[x].add2)%mod;
t[x*2].add=(t[x*2].add*t[x].add2+t[x].add)%mod;
t[x*2+1].add=(t[x*2+1].add*t[x].add2+t[x].add)%mod;
t[x].add=0;t[x].add2=1;
}
void change(long long x,long long a,long long b,long long s)
{
if(a<=t[x].l&&b>=t[x].r)
{
t[x].pre=(t[x].pre+s*(t[x].r-t[x].l+1))%mod;
t[x].add=(t[x].add+s)%mod;
return ;
}
spread(x);
t[x].pre=t[x*2].pre+t[x*2+1].pre;
long long mid=(t[x].l+t[x].r)>>1;
if(a<=mid)
{
change(x*2,a,b,s);
}
if(b>mid)
{
change(x*2+1,a,b,s);
}
t[x].pre=(t[x*2].pre+t[x*2+1].pre)%mod;
return ;
}
void qchange(long long x,long long a,long long b,long long s)
{
if(a<=t[x].l&&b>=t[x].r)
{
t[x].pre=(s*t[x].pre)%mod;
t[x].add2=(t[x].add2*s)%mod;
t[x].add=(t[x].add*s)%mod;
return ;
}
spread(x);
t[x].pre=(t[x*2].pre+t[x*2+1].pre)%mod;
long long mid=(t[x].l+t[x].r)>>1;
if(a<=mid)
{
qchange(x*2,a,b,s);
}
if(b>mid)
{
qchange(x*2+1,a,b,s);
}
t[x].pre=(t[x*2].pre+t[x*2+1].pre)%mod;
return ;
}
long long ask(long long x,long long a,long long b)
{
if(a<=t[x].l&&b>=t[x].r)
{
return t[x].pre;
}
spread(x);
long long ans=0;
long long mid=t[x].l+t[x].r>>1;
if(a<=mid)
{
ans+=(ask(x*2,a,b))%mod;
}
if(b>mid)
{
ans+=(ask(x*2+1,a,b))%mod;
}
return ans;
}
int main()
{
cin>>n>>m>>mod;
for(int i=1;i<=n;i++)
{
cin>>c[i];
}
build(1,1,n);
for(int i=1;i<=m;i++)
{
int q;
cin>>q;
if(q==2)
{
int x,y,z;
cin>>x>>y>>z;
change(1,x,y,z);
}
if(q==3)
{
int x,y;
cin>>x>>y;
cout<<ask(1,x,y)%mod<<endl;
}
if(q==1)
{
int x,y,z;
cin>>x>>y>>z;
qchange(1,x,y,z);
}
}
return 0;
}
线段树的结构体一定要开4倍(本人开了2倍调了2个星期)【哭死】