#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e5 + 10;
struct tree {
int l, r, idx, tagj, tagc, v;
} tr[N << 2];
int n, q, mod, a[N];
void pushup (int idx) {
tr[idx].v = tr[idx << 1].v + tr[(idx << 1) | 1].v;
tr[idx].v %= mod;
return ;
}
void build (int l, int r, int idx) {
if (l == r) {
tr[idx] = {l, r, idx, 0, 1, a[l]};
return ;
}
tr[idx] = {l, r, idx, 0, 1, 0};
int mid = (l + r) >> 1;
build (l, mid, idx << 1);
build (mid + 1, r, (idx << 1) | 1);
pushup(idx);
}
void pushdown (int idx) {
int t1 = tr[idx].tagc;
int t2 = tr[idx].tagj;
tr[idx].tagc = 1;
tr[idx].tagj = 0;
tr[idx << 1].v = tr[idx << 1].v * t1 + t2 * (tr[idx << 1].r - tr[idx << 1].l + 1);
tr[(idx << 1) | 1].v = tr[(idx << 1) | 1].v * t1 + t2 * (tr[(idx << 1) | 1].r - tr[(idx << 1) | 1].l + 1);
tr[idx << 1].v %= mod;
tr[(idx << 1) | 1].v %= mod;
tr[idx << 1].tagc *= t1;
tr[(idx << 1) | 1].tagc *= t1;
tr[(idx << 1) | 1].tagj = tr[(idx << 1) | 1].tagj * t1 + t2;
tr[idx << 1].tagj = tr[idx << 1].tagj * t1 + t2;
tr[idx << 1].tagj %= mod;
tr[(idx << 1) | 1].tagj %= mod;
}
void add (int l, int r, int idx, int v) {
if (tr[idx].l >= l && tr[idx].r <= r) {
tr[idx].tagj += v;
tr[idx].tagj %= mod;
tr[idx].v += (tr[idx].r - tr[idx].l + 1) * v;
tr[idx].v %= mod;
return ;
}
pushdown(idx);
int mid = (tr[idx].l + tr[idx].r) >> 1;
if (l <= mid) add (l, r, idx << 1, v);
if (mid + 1 <= r) add (l, r, (idx << 1) | 1, v);
pushup(idx);
}
void mul (int l, int r, int idx, int v) {
if (tr[idx].l >= l && tr[idx].r <= r) {
tr[idx].tagj *= v;
tr[idx].tagj %= mod;
tr[idx].tagc *= v;
tr[idx].v *= v;
tr[idx].v %= mod;
return ;
}
pushdown(idx);
int mid = (tr[idx].l + tr[idx].r) >> 1;
if (l <= mid) mul (l, r, idx << 1, v);
if (mid + 1 <= r) mul (l, r, (idx << 1) | 1, v);
pushup(idx);
}
int query (int l, int r, int idx) {
if (tr[idx].l >= l && tr[idx].r <= r) {
return tr[idx].v;
}
pushdown(idx);
int mid = (tr[idx].l + tr[idx].r) >> 1, t = 0;
if (l <= mid) t += query (l, r, idx << 1);
t %= mod;
if (mid + 1 <= r) t += query (l, r, (idx << 1) | 1);
t %= mod;
return t;
}
signed main() {
ios :: sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> q >> mod;
for (int i = 1; i <= n; i ++) cin >> a[i];
for (int i = 1; i <= n; i ++) a[i] %= mod;
build (1, n, 1);
for (int i = 1; i <= q; i ++) {
int op, x, y, k;
cin >> op;
if (op == 1) {
cin >> x >> y >> k;
mul (x, y, 1, k % mod);
} else if (op == 2) {
cin >> x >> y >> k;
add (x, y, 1, k % mod);
} else if (op == 3) {
cin >> x >> y;
cout << query (x, y, 1) % mod << "\n";
}
}
return 0;
}
本蒟蒻睿智的记录