不知道为什么
#include <bits/stdc++.h>
#define maxn 100010
using namespace std;
int n, p, m, a[maxn]; // 输入
long long w[maxn * 4], lzy_add[maxn * 4], lzy_mul[maxn * 4];
void pushup(int x) { // 修正
w[x] = (w[x * 2] + w[x * 2 + 1]) % p;
}
void build(int x, int l, int r) { // 建树
if(l == r) {
w[x] = a[l];
return;
}
int mid = (l + r) / 2;
lzy_mul[x] = 1;
build(x * 2, l, mid);
build(x * 2 + 1, mid + 1, r);
pushup(x);
}
void maketag(int x, int l, int r, long long num, bool type) { // 打标记
if(type) {
lzy_add[x] = (lzy_add[x] * num) % p;
lzy_mul[x] = (lzy_mul[x] * num) % p;
w[x] = (w[x] * num) % p;
} else {
lzy_add[x] = (lzy_add[x] + num) % p;
w[x] = (w[x] + num * (r - l + 1)) % p;
}
}
void pushdown(int x, int l, int r) { // 下传
int m = (l + r) / 2;
maketag(x * 2, l, m, lzy_mul[x], 1); // 先传乘,再传加
maketag(x * 2, l, m, lzy_add[x], 0);
maketag(x * 2 + 1, m + 1, r, lzy_mul[x], 1);
maketag(x * 2 + 1, m + 1, r, lzy_add[x], 0);
lzy_mul[x] = 1;
lzy_add[x] = 0;
}
bool inrange(int l, int r, int L, int R) { // 完全包含
if(l >= L && r <= R) return 1;
return 0;
}
bool outofrange(int l, int r, int L, int R) { // 完全不包含
if(r < L || l > R) return 1;
return 0;
}
int query(int x, int l, int r, int L, int R) { // 查询
if(inrange(l, r, L, R)) { // 全包含直接返和
return w[x] % p;
} else if(outofrange(l, r, L, R)) { // 不全包含返 0
return 0;
} else { // 否则分两段算
int mid = (l + r) / 2;
pushdown(x, l, r);
return (query(2 * x, l, mid, L, R) + query(2 * x + 1, mid + 1, r, L, R)) % p;
}
}
void update_add(int x, int l, int r, int L, int R, long long num) { // 加
if(inrange(l, r, L, R)) { // 全包含直接标
maketag(x, l, r, num, 0);
} else if(!outofrange(l, r, L, R)) { // 包含一部分分两段标记
int mid = (l + r) / 2;
update_add(2 * x, l, mid, L, R, num);
update_add(2 * x + 1, mid + 1, r, L, R, num);
pushup(x);
}
}
void update_mul(int x, int l, int r, int L, int R, long long num) { // 乘
if(inrange(l, r, L, R)) { // 全包含直接标
maketag(x, l, r, num, 1);
} else if(!outofrange(l, r, L, R)) { // 包含一部分分两段标记
int mid = (l + r) / 2;
update_mul(2 * x, l, mid, L, R, num);
update_mul(2 * x + 1, mid + 1, r, L, R, num);
pushup(x);
}
}
signed main() {
cin >> n >> p;
for(int i = 1; i <= n; i++) cin >> a[i];
build(1, 1, n);
cin >> m;
while(m--) {
int op, t, g;
long long c;
cin >> op;
if(op == 1) {
cin >> t >> g >> c;
update_mul(1, 1, n, t, g, c);
} else if(op == 2) {
cin >> t >> g >> c;
update_add(1, 1, n, t, g, c);
} else {
cin >> t >> g;
cout << query(1, 1, n, t, g) << '\n';
}
}
return 0;
}