样例可以过
#include <cstdio>
const int N = 4e5 + 9;
#define int long long
int sum[N], tag1[N], tag2[N];
bool isTag2[N];
int n, q, m;
void pushup(int id) {
sum[id] = (sum[id << 1] + sum[id << 1 | 1]) % m;
}
void build(int id, int L, int R) {
if (L == R) {
scanf("%lld", &sum[id]);
sum[id] %= m;
return;
}
int mid = (L + R) >> 1;
build(id << 1, L, mid);
build(id << 1 | 1, mid + 1, R);
pushup(id);
}
void initTag2(int id) {
if (!isTag2[id])
tag2[id] = 1;
}
void changeTag2(int id1, int id2, int L, int R) {
// id1的tag2修改id2
sum[id2] = (1LL * sum[id2] * tag2[id1]) % m;
tag2[id2] = (1LL * tag2[id2] * tag2[id1]) % m;
isTag2[id2] = true;
}
void changeTag1(int id1, int id2, int L, int R) {
// id1的tag1修改id2
sum[id2] = (long long)(sum[id2] + ((R - L + 1) % m) * (tag1[id1])) % m;
tag1[id2] = (tag1[id1] + tag1[id2]) % m;
}
void pushdown(int id, int L, int R) {
initTag2(id << 1), initTag2(id << 1 | 1);
int mid = (L + R) >> 1;
if (isTag2[id]) {
changeTag2(id, id << 1, L, mid);
changeTag2(id, id << 1 | 1, mid + 1, R);
}
changeTag1(id, id << 1, L, mid);
changeTag1(id, id << 1 | 1, mid + 1, R);
isTag2[id] = false;
tag1[id] = 0;
}
int query(int id, int L, int R, int qL, int qR) {
if (L == qL && R == qR) {
return sum[id];
}
pushdown(id, L, R);
int mid = (L + R) >> 1;
if (qR <= mid)
return query(id << 1, L, mid, qL, qR);
else if (qL > mid)
return query(id << 1 | 1, mid + 1, R, qL, qR);
else
return (query(id << 1, L, mid, qL, mid) + query(id << 1 | 1, mid + 1, R, mid + 1, qR)) % m;
}
void add(int id, int L, int R, int qL, int qR, int k) {
if (L == qL && R == qR) {
sum[id] = (sum[id] + ((R - L + 1) * k) % m) % m;
tag1[id] = (tag1[id] + k) % m;
return;
}
pushdown(id, L, R);
int mid = (L + R) >> 1;
if (qR <= mid)
add(id << 1, L, mid, qL, qR, k);
else if (qL > mid)
add(id << 1 | 1, mid + 1, R, qL, qR, k);
else {
add(id << 1, L, mid, qL, mid, k);
add(id << 1 | 1, mid + 1, R, mid + 1, qR, k);
}
pushup(id);
}
void mult(int id, int L, int R, int qL, int qR, int k) {
// puts("1");
if (L == qL && R == qR) {
initTag2(id);
// printf("%d\n", tag1[id]);
sum[id] = (1LL * sum[id] * k) % m;
if (tag1[id] == 0) {
// puts("11111111----1");
tag2[id] = (1LL * tag2[id] * k) % m;
isTag2[id] = true;
} else {
tag1[id] = (1LL * tag1[id] * k) % m;
}
return;
}
pushdown(id, L, R);
int mid = (L + R) >> 1;
if (qR <= mid)
mult(id << 1, L, mid, qL, qR, k);
else if (qL > mid)
mult(id << 1 | 1, mid + 1, R, qL, qR, k);
else {
mult(id << 1, L, mid, qL, mid, k);
mult(id << 1 | 1, mid + 1, R, mid + 1, qR, k);
}
pushup(id);
}
signed main() {
scanf("%lld%lld%lld", &n, &q, &m);
build(1, 1, n);
while (q--) {
int opt, x, y, k;
scanf("%lld", &opt);
if (opt < 1 || opt > 3) {
++q;
continue;
}
scanf("%lld%lld", &x, &y);
if (opt != 3) {
scanf("%lld", &k);
k %= m;
}
if (opt == 2) {
add(1, 1, n, x, y, k);
} else if (opt == 1) {
// puts("1");
mult(1, 1, n, x, y, k);
} else if (opt == 3) {
printf("%lld\n", query(1, 1, n, x, y));
}
}
return 0;
}