code:
#include<iostream>
using namespace std;
// 乘法优先:
// 有两种情况:
// 1. 先执行乘,再执行加:a = a*tag_mul+add
// 2. 先执行加,再执行乘:a = (a+tag_add)*tag_mul = a*mul + tag_add * mul
// 转化为一种:
// a = a*tag_mul+tag_add 在mul时,把tag_add也乘上mul,即a*mul + tag_add * mul
// 区间和变成: sum*tag_mul + (r-l+1)*tag_add
struct node
{
long long l;
long long r;
long long val;
long long tag_mul,tag_add;
bool tm,ta;
};
long long n,m,mod;
long long a[100005];
node t[400005];
void bt(long long p,long long l,long long r)
{
t[p].l = l;
t[p].r = r;
t[p].tm = t[p].ta = 0;
t[p].tag_mul = 1;
t[p].tag_add = 0;
if(l == r)
{
t[p].val = a[l];
return ;
}
long long mid = (l+r)/2;
bt(p*2,l,mid);
bt(p*2+1,mid+1,r);
t[p].val = t[p*2].val + t[p*2+1].val;
t[p].val %= mod;
}
void down(long long p)
{
if(t[p].l == t[p].r)
{
return ;
}
if(t[p].tm == 1)
{
t[p*2].val *= t[p].tag_mul;
t[p*2+1].val *= t[p].tag_mul;
t[p*2].val %= mod;
t[p*2+1].val %= mod;
t[p*2].tm = t[p*2+1].tm = 1;
t[p*2].tag_mul *= t[p].tag_mul;
t[p*2+1].tag_mul *= t[p].tag_mul;
}
if(t[p].ta == 1)
{
t[p*2].val += (t[p*2].r-t[p*2].l+1)*t[p].tag_add;
t[p*2+1].val += (t[p*2+1].r-t[p*2+1].l+1)*t[p].tag_add;
t[p*2].val %= mod;
t[p*2+1].val %= mod;
t[p*2].ta = t[p*2+1].ta = 1;
t[p*2].tag_add += t[p].tag_add;
t[p*2+1].tag_add += t[p].tag_add;
}
t[p].tm = t[p].ta = 0;
t[p].tag_mul = 1;
t[p].tag_add = 0;
t[p].val = t[p*2].val + t[p*2+1].val;
t[p].val %= mod;
}
long long sum(long long p,long long l,long long r)
{
down(p);
if(l <= t[p].l && r >= t[p].r)
{
return t[p].val;
}
long long mid = (t[p].l+t[p].r) / 2;
long long ans = 0;
if(l <= mid)
{
ans = (ans+sum(p*2,l,r)) % mod;
}
if(r >= mid+1)
{
ans = (ans+sum(p*2+1,l,r)) % mod;
}
return ans % mod;
}
void mul(long long p,long long l,long long r,long long x)
{
if(l <= t[p].l && r >= t[p].r)
{
t[p].val *= x;
t[p].val %= mod;
t[p].tm = 1;
t[p].tag_mul *= x;
t[p].tag_add *= x; // ※
return ;
}
down(p);
long long mid = (t[p].l+t[p].r) / 2;
if(l <= mid)
{
mul(p*2,l,r,x);
}
if(r >= mid+1)
{
mul(p*2+1,l,r,x);
}
t[p].val = t[p*2].val + t[p*2+1].val;
t[p].val %= mod;
}
void add(long long p,long long l,long long r,long long x)
{
if(l <= t[p].l && r >= t[p].r)
{
t[p].val += (t[p].r-t[p].l+1)*x;
t[p].val %= mod;
t[p].ta = 1;
t[p].tag_add += x;
return ;
}
down(p);
long long mid = (t[p].l+t[p].r) / 2;
if(l <= mid)
{
add(p*2,l,r,x);
}
if(r >= mid+1)
{
add(p*2+1,l,r,x);
}
t[p].val = t[p*2].val + t[p*2+1].val;
t[p].val %= mod;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
cin >> n >> m >> mod;
for(long long i=1;i<=n;i++)
{
cin >> a[i];
a[i] %= mod;
}
bt(1,1,n);
for(long long i=1;i<=m;i++)
{
long long op;
cin >> op;
if(op == 1)
{
long long l,r,x;
cin >> l >> r >> x;
mul(1,l,r,x);
}
else if(op == 2)
{
long long l,r,x;
cin >> l >> r >> x;
add(1,l,r,x);
}
else
{
long long l,r;
cin >> l >> r;
cout << sum(1,l,r) % mod << endl;
}
}
return 0;
}