RT,样例过,数据全红
//
// main.cpp
// SegT_2
//
// Created by Mac on 2022/11/22.
//
#include <iostream>
#include <cstdio>
#define N 100005
#define ll long long
using namespace std;
ll n, m, p, op, x, y, k, a[N<<2], ans[N<<2], add[N<<2], mul[N<<2];
inline ll ls (ll x) { return x << 1 ; }
inline ll rs (ll x) { return x << 1 | 1 ; }
void flash (ll x, ll l, ll r, ll mu, ll ad) {
ans[x] = ans[x] * mu + ad * (r - l + 1);
mul[x] *= mu;
add[x] = add[x] * mu + ad;
ans[x] %= p; mul[x] %= p; add[x] %= p;
return;
}
void pushup (ll x) {
ans[x] = ans[ls(x)] + ans[rs(x)];
ans[x] %= p;
return;
}
void pushdown (ll x, ll l, ll r) {
ll mid = (l + r) >> 1;
flash(ls(x), l, mid, mul[x], add[x]);
flash(rs(x), mid+1, r, mul[x], add[x]);
add[x] = 0; mul[x] = 1;
return;
}
void build (ll l, ll r, ll pos) {
mul[pos] = 1;
if (l == r) {
ans[pos] = a[l];
return;
}
ll mid = (l + r) >> 1;
build(l, mid, ls(pos));
build(mid+1, r, rs(pos));
pushup(pos);
return;
}
void update_add (ll x, ll l, ll r, ll ul, ll ur, ll k) {
if (l >= ul && r <= ur) {
flash(x, l, r, 1, k);
return;
}
ll mid = (l + r) >> 1;
if (ul <= mid) update_add(ls(x), l, mid, ul, ur, k);
if (ur > mid) update_add(rs(x), mid+1, r, ul, ur, k);
pushup(x);
return;
}
void update_mul (ll x, ll l, ll r, ll ul, ll ur, ll k) {
if (l >= ul && r <= ur) {
flash(x, l, r, k, 0);
return;
}
ll mid = (l + r) >> 1;
if (ul <= mid) update_mul(ls(x), l, mid, ul, ur, k);
if (ur > mid) update_mul(rs(x), mid+1, r, ul, ur, k);
pushup(x);
return;
}
ll query (ll x, ll l, ll r, ll ql, ll qr) {
if (l >= ql && r <= qr) {
return ans[x];
}
pushdown(x, l, r);
ll mid = (l + r) >> 1, res = 0;
if (ql <= mid) res += query(ls(x), l, mid, ql, qr);
if (qr > mid) res += query(rs(x), mid+1, r, ql, qr);
return res % p;
}
int main(int argc, const char * argv[]) {
// insert code here...
// std::cout << "Hello, World!\n";
scanf("%lld%lld%lld", &n, &m, &p);
for (int i=1; i<=n; ++i) {
scanf("%lld", &a[i]);
a[i] %= p;
}
build (1, n, 1);
while (m--) {
scanf("%lld", &op);
switch (op) {
case 1:
scanf("%lld%lld%lld", &x, &y, &k);
update_mul(1, 1, n, x, y, k);
break;
case 2:
scanf("%lld%lld%lld", &x, &y, &k);
update_add(1, 1, n, x, y, k);
break;
case 3:
scanf("%lld%lld", &x, &y);
printf("%lld\n", query(1, 1, n, x, y));
break;
default:
break;
}
}
return 0;
}