AC记录
#include<bits/stdc++.h>
using namespace std;
#define L rt<<1
#define R rt<<1|1
#define ll long long
inline ll read()
{
ll x=0,f=1;
char c=getchar();
while(c<'0'||c>'9')
{
if(c=='-')f=-f;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=(x<<3)+(x<<1)+c-'0';
c=getchar();
}
return x*f;
}
const int N=1e5+1;
int n,m,p;
struct SegTree{
int l,r;
ll sum;
ll mul_tag,add_tag;
}t[4*N];
ll a[N];
inline void Pushup(int rt){t[rt].sum=(t[L].sum+t[R].sum)%p;return;}
inline void Build(int rt,int l,int r)
{
t[rt].l=l,t[rt].r=r,t[rt].mul_tag=1;
if(l==r){t[rt].sum=a[l]%p;return;}
int mid=(l+r)>>1;
Build(L,l,mid);
Build(R,mid+1,r);
Pushup(rt);
return;
}
inline void Pushdown(int rt)
{
t[L].sum=(t[rt].mul_tag*t[L].sum+((t[L].r-t[L].l+1)*t[rt].add_tag)%p)%p;
t[R].sum=(t[rt].mul_tag*t[R].sum+((t[R].r-t[R].l+1)*t[rt].add_tag)%p)%p;
t[L].mul_tag=(t[L].mul_tag*t[rt].mul_tag)%p;
t[R].mul_tag=(t[R].mul_tag*t[rt].mul_tag)%p;
t[L].add_tag=(t[rt].mul_tag*t[L].add_tag+t[rt].add_tag)%p;
t[R].add_tag=(t[rt].mul_tag*t[R].add_tag+t[rt].add_tag)%p;
t[rt].mul_tag=1,t[rt].add_tag=0;
return;
}
inline void Update_add(int rt,int l,int r,ll C)
{
if(l<=t[rt].l&&t[rt].r<=r)
{
t[rt].add_tag=(t[rt].add_tag+C)%p;
t[rt].sum=(t[rt].sum+C*(t[rt].r-t[rt].l+1))%p;
return;
}
Pushdown(rt);
int mid=(t[rt].l+t[rt].r)>>1;
if(l<=mid)Update_add(L,l,r,C);
if(r>mid) Update_add(R,l,r,C);
Pushup(rt);
return;
}
inline void Update_mul(int rt,int l,int r,ll C)
{
if(l<=t[rt].l&&t[rt].r<=r)
{
t[rt].add_tag=(t[rt].add_tag*C)%p;
t[rt].mul_tag=(t[rt].mul_tag*C)%p;
t[rt].sum=(t[rt].sum*C)%p;
return;
}
Pushdown(rt);
int mid=(t[rt].l+t[rt].r)>>1;
if(l<=mid)Update_mul(L,l,r,C);
if(r>mid) Update_mul(R,l,r,C);
Pushup(rt);
return;
}
inline ll Getsum(int rt,int l,int r)
{
if(l<=t[rt].l&&t[rt].r<=r)return t[rt].sum;
Pushdown(rt);
int mid=(t[rt].l+t[rt].r)>>1;
ll ans=0;
if(l<=mid)ans=(ans+Getsum(L,l,r))%p;
if(r>mid) ans=(ans+Getsum(R,l,r))%p;
return ans;
}
int main()
{
n=read(),m=read(),p=read();
for(ll i=1;i<=n;i++) a[i]=read();
Build(1,1,n);
int op,l,r;ll x;
while(m--)
{
op=read(),l=read(),r=read();
if(op==1)
{
x=read();
Update_mul(1,l,r,x);
}
else if(op==2)
{
x=read();
Update_add(1,l,r,x);
}
else printf("%lld\n",Getsum(1,l,r));
}
return 0;
}