#include #define ll long long ll read() { ll w = 1, q = 0; char ch = ' '; while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar(); if (ch == '-') w = -1, ch = getchar(); while (ch >= '0' && ch <= '9') q = (ll)q * 10 + ch - '0', ch = getchar(); return (ll)w * q; } int n, m; ll mod; ll a[100005], sum[400005], mul[400005], laz[400005]; void up(int i) { sum[i] = (sum[(i << 1)] + sum[(i << 1) | 1]) % mod; } void pd(int i, int s, int t) { int l = (i << 1), r = (i << 1) | 1, mid = (s + t) >> 1; if (mul[i] != 1) { // 懒标记传递,两个懒标记 mul[l] *= mul[i]; mul[l] %= mod; mul[r] *= mul[i]; mul[r] %= mod; laz[l] *= mul[i]; laz[l] %= mod; laz[r] *= mul[i]; laz[r] %= mod; sum[l] *= mul[i]; sum[l] %= mod; sum[r] *= mul[i]; sum[r] %= mod; mul[i] = 1; } if (laz[i]) { // 懒标记传递 sum[l] += laz[i] * (mid - s + 1); sum[l] %= mod; sum[r] += laz[i] * (t - mid); sum[r] %= mod; laz[l] += laz[i]; laz[l] %= mod; laz[r] += laz[i]; laz[r] %= mod; laz[i] = 0; } return; } void build(int s, int t, int i) { mul[i] = 1; if (s == t) { sum[i] = a[s]; return; } int mid = s + ((t - s) >> 1); build(s, mid, i << 1); // 建树 build(mid + 1, t, (i << 1) | 1); up(i); } void chen(int l, int r, int s, int t, int i, ll z) { int mid = s + ((t - s) >> 1); if (l <= s && t <= r) { mul[i] *= z; mul[i] %= mod; // 这是取模的 laz[i] *= z; laz[i] %= mod; // 这是取模的 sum[i] *= z; sum[i] %= mod; // 这是取模的 return; } pd(i, s, t); if (mid >= l) chen(l, r, s, mid, (i << 1), z); if (mid + 1 <= r) chen(l, r, mid + 1, t, (i << 1) | 1, z); up(i); } void add(int l, int r, int s, int t, int i, ll z) { int mid = s + ((t - s) >> 1); if (l <= s && t <= r) { sum[i] += z * (t - s + 1); sum[i] %= mod; // 这是取模的 laz[i] += z; laz[i] %= mod; // 这是取模的 return; } pd(i, s, t); if (mid >= l) add(l, r, s, mid, (i << 1), z); if (mid + 1 <= r) add(l, r, mid + 1, t, (i << 1) | 1, z); up(i); } ll getans(int l, int r, int s, int t, int i) { // 得到答案,可以看下上面懒标记助于理解 int mid = s + ((t - s) >> 1); ll tot = 0; if (l <= s && t <= r) return sum[i]; pd(i, s, t); if (mid >= l) tot += getans(l, r, s, mid, (i << 1)); tot %= mod; if (mid + 1 <= r) tot += getans(l, r, mid + 1, t, (i << 1) | 1); return tot % mod; } int main() { // 读入 int i, j, x, y, bh; ll z; n = read(); m = read(); mod = read(); for (i = 1; i <= n; i++) a[i] = read(); build(1, n, 1); // 建树 for (i = 1; i <= m; i++) { bh = read(); if (bh == 1) { x = read(); y = read(); z = read(); chen(x, y, 1, n, 1, z); } else if (bh == 2) { x = read(); y = read(); z = read(); add(x, y, 1, n, 1, z); } else if (bh == 3) { x = read(); y = read(); printf("%lld\n", getans(x, y, 1, n, 1)); } } return 0; }