样例过了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<stack>
#include<cstring>
#include<string>
#include<functional>
#include<map>
#define int long long
using namespace std;
int red() {
int op = 1, x = 0;
char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') {
op = -1;
}
ch = getchar();
}
while(isdigit(ch)) {
x = x * 10LL + ch - '0';
ch = getchar();
}
return x * op;
}
const int maxn = 1e5 + 10;
int n, q, m, root = 1;
int a[maxn];
int lp[maxn << 2], rp[maxn << 2], val[maxn << 2], lza[maxn << 2], lzm[maxn << 2];
void update(int now) {
int lc = now << 1, rc = (now << 1) + 1;
val[now] = val[lc] + val[rc];
val[now] %= m;
}
void build(int now, int l, int r) {
lp[now] = l, rp[now] = r;
lzm[now] = 1;
if(l == r) {
val[now] = a[l] % m;
return;
}
int mid = (lp[now] + rp[now]) >> 1, lc = now << 1, rc = (now << 1) + 1;
build(lc, l, mid);
build(rc, mid + 1, r);
update(now);
}
void lazya(int now, int key) {
lza[now] += key;
lza[now] %= m;
val[now] += (rp[now] - lp[now] + 1) * key;
val[now] %= m;
}
void lazym(int now, int key) {
lza[now] *= key;
lza[now] %= m;
lzm[now] *= key;
lzm[now] %= m;
val[now] *= key;
val[now] %= m;
}
void pushdown(int now) {
int lc = now << 1, rc = (now << 1) + 1;
lazym(lc, lzm[now]);
lazym(rc, lzm[now]);
lazya(lc, lza[now]);
lazya(rc, lza[now]);
lzm[now] = 1;
lza[now] = 0;
}
void add(int now, int l, int r, int key) {
if(l <= lp[now] && rp[now] <= r) {
lazya(now, key);
return;
}
if(lza[now]) {
pushdown(now);
}
int mid = (lp[now] + rp[now]) >> 1, lc = now << 1, rc = (now << 1) + 1;
if(l <= mid) {
add(lc, l, r, key);
}
if(mid < r) {
add(rc, l, r, key);
}
update(now);
}
void mul(int now, int l, int r, int key) {
if(l <= lp[now] && rp[now] <= r) {
lazym(now, key);
return;
}
if(lzm[now] > 1) {
pushdown(now);
}
int mid = (lp[now] + rp[now]) >> 1, lc = now << 1, rc = (now << 1) + 1;
if(l <= mid) {
mul(lc, l, r, key);
}
if(mid < r) {
mul(rc, l, r, key);
}
update(now);
}
int query(int now, int l, int r) {
if(l <= lp[now] && rp[now] <= r) {
return val[now];
}
if(lza[now] || lzm[now] > 1) {
pushdown(now);
}
int mid = (lp[now] + rp[now]) >> 1, lc = now << 1, rc = (now << 1) + 1;
int res = 0;
if(l <= mid) {
res += query(lc, l, r);
res %= m;
}
if(mid < r) {
res += query(rc, l, r);
res %= m;
}
return res;
}
signed main() {
n = red(), q = red(), m = red();
for(int i = 1; i <= n; ++i) {
a[i] = red();
}
build(1, 1, n);
for(int i = 1; i <= q; ++i) {
int op = red(), x = red(), y = red(), k;
if(op == 1) {
k = red();
mul(root, x, y, k);
} else if(op == 2) {
k = red();
add(root, x, y, k);
} else {
int res = query(root, x, y);
cout << res << endl;
}
}
return 0;
}