社区讨论
30分求调,只过了1,3,4,感觉能模的地方都模了
P3373【模板】线段树 2参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @m5ffie73
- 此快照首次捕获于
- 2025/01/02 22:36 去年
- 此快照最后确认于
- 2025/11/04 12:03 4 个月前
CPP
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int MAXN = 1e5 + 10;
#define LEFT (i << 1)
#define RIGHT ((i << 1) + 1)
int n, q;
ll m, a[MAXN];
ll tree[MAXN << 2], lazy_add[MAXN << 2], lazy_mul[MAXN << 2];
void push_up(int i) {
tree[i] = (tree[LEFT] + tree[RIGHT]) % m;
}
void push_down(int i, int l, int r) {
if (lazy_mul[i] != 1) {
tree[LEFT] = (tree[LEFT] * lazy_mul[i]) % m;
tree[RIGHT] = (tree[RIGHT] * lazy_mul[i]) % m;
lazy_mul[LEFT] = (lazy_mul[LEFT] * lazy_mul[i]) % m;
lazy_mul[RIGHT] = (lazy_mul[RIGHT] * lazy_mul[i]) % m;
}
if (lazy_add[i] != 0) {
int mid = (l + r) >> 1;
tree[LEFT] = (tree[LEFT] + lazy_add[i] * (mid - l + 1) % m) % m;
tree[RIGHT] = (tree[RIGHT] + lazy_add[i] * (r - mid) % m) % m;
lazy_add[LEFT] = (lazy_add[LEFT] * lazy_mul[i] % m + lazy_add[i]) % m;
lazy_add[RIGHT] = (lazy_add[RIGHT] * lazy_mul[i] % m + lazy_add[i]) % m;
}
lazy_mul[i] = 1;
lazy_add[i] = 0;
}
void build(int i, int l, int r) {
lazy_mul[i] = 1;
lazy_add[i] = 0;
if (l == r) {
tree[i] = a[l];
return;
}
int mid = (l + r) >> 1;
build(LEFT, l, mid);
build(RIGHT, mid + 1, r);
push_up(i);
}
// a: *, b: +
void update(int i, int l, int r, int L, int R, ll a, ll b) {
if (l >= L && r <= R) {
tree[i] = (tree[i] * a) % m;
tree[i] = (tree[i] + b * (r - l + 1) % m) % m;
lazy_mul[i] = (lazy_mul[i] * a) % m;
lazy_add[i] = (lazy_add[i] * a % m + b) % m;
return;
}
push_down(i, l, r);
int mid = (l + r) >> 1;
if (mid >= L)
update(LEFT, l, mid, L, R, a, b);
if (mid < R)
update(RIGHT, mid + 1, r, L, R, a, b);
push_up(i);
return;
}
ll query(int i, int l, int r, int L, int R) {
if (l >= L && r <= R)
return tree[i];
push_down(i, l, r);
int mid = (l + r) >> 1;
ll ans = 0;
if (mid >= L)
ans += query(LEFT, l, mid, L, R);
if (mid < R)
ans += query(RIGHT, mid + 1, r, L, R);
ans %= m;
push_up(i);
return ans;
}
void solve() {
cin >> n >> q >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
build(1, 1, n);
while (q--) {
int op, x, y;
cin >> op >> x >> y;
if (op == 1) {
ll k;
cin >> k;
update(1, 1, n, x, y, k % m, 0);
} else if (op == 2) {
ll k;
cin >> k;
update(1, 1, n, x, y, 1, k % m);
} else {
ll ans = query(1, 1, n, x, y);
cout << ans << '\n';
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
solve();
return 0;
}
回复
共 2 条回复,欢迎继续交流。
正在加载回复...