Files
python/TangDou/AcWing/SegmentTree/P3373_XDS.cpp
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

112 lines
2.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <bits/stdc++.h>
using namespace std;
const int N = 1000010;
int n, m, p;
// 线段树模板
#define LL long long
#define ls u << 1
#define rs u << 1 | 1
#define mid ((l + r) >> 1)
struct Node {
int l, r;
int mu, add;
LL sum;
} tr[N << 2];
void pushup(int u) {
tr[u].sum = (tr[ls].sum + tr[rs].sum) % p;
}
void build(int u, int l, int r) {
tr[u].l = l, tr[u].r = r, tr[u].mu = 1;
if (l == r) {
cin >> tr[u].sum;
return;
}
build(ls, l, mid), build(rs, mid + 1, r);
pushup(u);
}
void pushdown(int u) {
if (tr[u].add == 0 && tr[u].mu == 1) return; // 默认懒标记
int &mu = tr[u].mu, &add = tr[u].add; // 此时的add懒标记,已经处理过了
tr[ls].sum = ((LL)mu * tr[ls].sum % p + (LL)(tr[ls].r - tr[ls].l + 1) * add % p) % p;
tr[rs].sum = ((LL)mu * tr[rs].sum % p + (LL)(tr[rs].r - tr[rs].l + 1) * add % p) % p;
tr[ls].mu = (LL)tr[ls].mu * mu % p;
tr[rs].mu = (LL)tr[rs].mu * mu % p;
tr[ls].add = ((LL)tr[ls].add * mu % p + add) % p;
tr[rs].add = ((LL)tr[rs].add * mu % p + add) % p;
mu = 1, add = 0; // 清空懒标记
}
void add(int u, int L, int R, int v) {
int l = tr[u].l, r = tr[u].r;
if (l >= L && r <= R) {
tr[u].add = ((LL)tr[u].add + v) % p;
tr[u].sum = ((LL)tr[u].sum + v * ((LL)tr[u].r - tr[u].l + 1) % p) % p;
return;
}
if (l > R || r < L) return;
pushdown(u);
add(ls, L, R, v), add(rs, L, R, v);
pushup(u);
}
void mu(int u, int L, int R, int v) {
int l = tr[u].l, r = tr[u].r;
if (l >= L && r <= R) {
tr[u].add = (LL)tr[u].add * v % p; // 比较重要的一步,add要在这里乘上v,因为后面可能要加其他的数而那些数其实是不用乘k的
tr[u].mu = (LL)tr[u].mu * v % p;
tr[u].sum = (LL)tr[u].sum * v % p;
return;
}
if (l > R || r < L) return;
pushdown(u);
mu(ls, L, R, v), mu(rs, L, R, v);
pushup(u);
}
LL query(int u, int L, int R) {
int l = tr[u].l, r = tr[u].r;
if (l >= L && r <= R) return tr[u].sum;
if (l > R || r < L) return 0;
pushdown(u);
return (query(ls, L, R) + query(rs, L, R)) % p;
}
signed main() {
// 文件输入输出
#ifndef ONLINE_JUDGE
freopen("P3373.in", "r", stdin);
#endif
// 加快读入
ios::sync_with_stdio(false), cin.tie(0);
cin >> n >> m >> p;
build(1, 1, n);
while (m--) {
int op, l, r;
cin >> op >> l >> r;
if (op == 1) {
int k;
cin >> k;
mu(1, l, r, k);
} else if (op == 2) {
int k;
cin >> k;
add(1, l, r, k);
} else
printf("%lld\n", query(1, l, r));
}
return 0;
}