社区讨论
初学线段树,思路应该较清晰,求调
P3373【模板】线段树 2参与者 5已保存回复 8
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 8 条
- 当前快照
- 1 份
- 快照标识符
- @lo8x8n9b
- 此快照首次捕获于
- 2023/10/28 02:03 2 年前
- 此快照最后确认于
- 2023/10/28 02:03 2 年前
rt,一些变量名已在程序中标出。
CPP#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, m, p, a[N], lazy1[N << 2], lazy2[N << 2], sum[N << 2];
//lazy1 记录乘 lazy2 记录加
int ls (int k) {
return (k << 1);
}
int rs (int k) {
return (k << 1 | 1);
}
void pushup (int k) {
sum[k] = (sum[ls(k)] + sum[rs(k)]) % p;
}
void pushdown (int k, int ln, int rn) {
sum[ls(k)] = (sum[ls(k)] * lazy2[ls(k)] + lazy1[k] * ln) % p;
sum[rs(k)] = (sum[rs(k)] * lazy2[rs(k)] + lazy1[k] * rn) % p;
lazy2[ls(k)] = (lazy2[ls(k)] * lazy2[k]) % p;
lazy2[rs(k)] = (lazy2[rs(k)] * lazy2[k]) % p;
lazy1[ls(k)] = (lazy1[ls(k)] * lazy2[k] + lazy1[k]) % p;
lazy1[rs(k)] = (lazy1[rs(k)] * lazy2[k] + lazy1[k]) % p;
lazy1[k] = 0;
lazy2[k] = 1;
}
void build (int l, int r, int k) {
lazy2[k] = 1;
if (l == r) {
sum[k] = a[l] % p;
return ;
}
int mid = (l + r) >> 1;
build (l, mid, ls(k));
build (mid + 1, r, rs(k));
pushup(k);
}
void updata1 (int L, int R, int v, int l, int r, int k) { //*
if (L <= l and r <= R) {
lazy1[k] = (lazy1[k] * v) % p;
lazy2[k] = (lazy2[k] * v) % p;
sum[k] = (sum[k] * v) % p;
return ;
}
int mid = (l + r) >> 1;
pushdown (k, mid - l + 1, r - mid);
if (L <= mid) updata1 (L, R, v, l, mid, ls(k));
if (R > mid) updata1 (L, R, v, mid + 1, r, rs(k));
pushup (k);
}
void updata2 (int L, int R, int v, int l, int r, int k) { //+
if (L <= l and r <= R) {
lazy1[k] = (lazy1[k] + k) % p;
sum[k] = (sum[k] + v * (r - l + 1)) % p;
return ;
}
int mid = (l + r) >> 1;
pushdown (k, mid - l + 1, r - mid);
if (L <= mid) updata2 (L, R, v, l, mid, ls(k));
if (R > mid) updata2 (L, R, v, mid + 1, r, rs(k));
pushup (k);
}
int query (int L, int R, int l, int r, int k) {
if (L <= l and r <= R) {
return sum[k] % k;
}
int mid = (l + r) >> 1, res = 0;
pushdown (k, mid - l + 1, r - mid);
if (L <= mid) res = (res + query(L, R, l, mid, ls(k))) % p;
if (R > mid) res = (res + query (L, R, mid + 1, r, rs(k))) % p;
return res;
}
int main () {
scanf ("%d%d%d", &n, &m, &p);
for (int i = 1; i <= n; ++ i) scanf ("%d", &a[i]);
while (m --) {
int opt, x, y, k;
scanf ("%d%d%d", &opt, &x, &y);
if (opt == 1) {
scanf ("%d", &k);
updata1 (x, y, k, 1, n, 1);
}
else if (opt == 2) {
scanf ("%d", &k);
updata2 (x, y, k, 1, n, 1);
}
else {
printf ("%d\n", query(x, y, 1, n, 1));
}
}
return 0;
}
回复
共 8 条回复,欢迎继续交流。
正在加载回复...