【模板】线段树 2 - 洛谷https://www.luogu.com.cn/problem/P3373
#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <cstring>
#include <set>
#include <unordered_map>
#include <cmath>
#include <map>
#include <cctype>
#include <cstdlib>
#include <deque>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int MN = 65005;
const int MAXN = 1000010;
const int INF = 0x3f3f3f3f;
#define IOS ios::sync_with_stdio(false)
#define lowbit(x) ((x)&(-x))
struct tree {
int l, r;
int sum;
int mul, add;
} tr[MAXN];
int a[MAXN];
int n, m, mod;
inline void eval(tree &t, int mul, int add) {
t.sum = ((ll)t.sum * mul + (ll)(t.r - t.l + 1) * add) % mod;
t.mul = ((ll)t.mul * mul) % mod;
t.add = ((ll)t.add * mul + add) % mod;
}
inline void push_down(int p) {
eval(tr[p << 1], tr[p].mul, tr[p].add);
eval(tr[p << 1 | 1], tr[p].mul, tr[p].add);
tr[p].mul = 1, tr[p].add = 0;
}
inline void push_up(int p) {
tr[p].sum = (tr[p << 1].sum + tr[p << 1 | 1].sum) % mod;
}
void build(int p, int l, int r) {
if (l == r)
return void(tr[p] = {l, r, a[l], 1, 0});
tr[p] = {l, r, 0, 1, 0};
int mid = l + r >> 1;
build(p << 1, l, mid);
build(p << 1 | 1, mid + 1, r);
push_up(p);
}
void update(int p, int l, int r, int mul, int add) {
if (tr[p].l >= l && tr[p].r <= r) {
eval(tr[p], mul, add);
return;
}
push_down(p);
int mid = tr[p].l + tr[p].r >> 1;
if (mid >= l)
update(p << 1, l, r, mul, add);
if (mid < r)
update(p << 1 | 1, l, r, mul, add);
push_up(p);
}
int query(int p, int l, int r) {
if (tr[p].l >= l && tr[p].r <= r) {
return tr[p].sum;
}
push_down(p);
int mid = tr[p].l + tr[p].r >> 1;
int ans = 0;
if (mid >= l)
ans = query(p << 1, l, r);
if (mid < r)
ans = (ans + query(p << 1 | 1, l, r)) % mod;
return ans;
}
int main() {
scanf("%d %d %d", &n, &m, &mod);
for (int i = 1; i <= n; i++) {
scanf("%d", a + i);
}
build(1, 1, n);
int t, x, y, k;
while (m--) {
scanf("%d %d %d", &t, &x, &y);
if (t == 1) {
scanf("%d", &k);
update(1, x, y, k, 0);
} else if (t == 2) {
scanf("%d", &k);
update(1, x, y, 1, k);
} else {
printf("%d\n", query(1, x, y));
}
}
return 0;
}