AcWing 243. 一个简单的整数问题2 (线段树 + 懒标记 模板)(树状数组)
题目链接:243. 一个简单的整数问题2 - AcWing题库
题目大意:
给定一个长度为 N 的数列 A,以及 M 条指令,每条指令可能是以下两种之一:
C l r d,表示把 A[l],A[l+1],…,A[r] 都加上 d。Q l r,表示询问数列中第 l∼r 个数的和。
对于每个询问,输出一个整数表示答案。
线段树:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 200086;
int n, m;
int w[N];
struct node {
int l, r;
int s, add;
} e[N << 2];
void pushup(int u) {
e[u].s = e[u << 1].s + e[u << 1 | 1].s;
}
void pushdown(int u) {
auto &root = e[u], &lf = e[u << 1], &ri = e[u << 1 | 1];
if (root.add) {//懒标记不处理根节点
lf.add += root.add;
ri.add += root.add;
lf.s += (lf.r - lf.l + 1) * root.add;
ri.s += (ri.r - ri.l + 1) * root.add;
root.add = 0;
}
}
void build(int u, int l, int r) {
if (l == r) e[u] = {l, r, w[l]};
else {
e[u] = {l, r};
int mid = (l + r) >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
}
void modify(int u, int l, int r, int x) {
if (l <= e[u].l && e[u].r <= r) {
e[u].add += x;
e[u].s += (e[u].r - e[u].l + 1) * x;
} else {
pushdown(u);
int mid = (e[u].l + e[u].r) >> 1;
if (l <= mid) modify(u << 1, l, r, x);
if (r > mid) modify(u << 1 | 1, l, r, x);
pushup(u);
}
}
int query(int u, int l, int r) {
pushdown(u);
if (l <= e[u].l && e[u].r <= r) return e[u].s;
else {
int res = 0;
int mid = (e[u].l + e[u].r) >> 1;
if (l <= mid) res = query(u << 1, l, r);
if (r > mid) res += query(u << 1 | 1, l, r);
return res;
}
}
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> w[i];
build(1, 1, n);
while (m--) {
char c;
int l, r, x;
cin >> c >> l >> r;
if (c == 'Q') cout << query(1, l, r) << endl;
else {
cin >> x;
modify(1, l, r, x);
}
}
return 0;
}
树状数组:

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 200086;
int n, m;
int w[N];
int d[N], id[N];
int lowbit(int x) {
return x & -x;
}
void add(int arr[], int i, int x) {
for (; i <= n; i += lowbit(i)) arr[i] += x;
}
int sum(int arr[], int i) {
int res = 0;
for (; i; i -= lowbit(i)) res += arr[i];
return res;
}
int summ(int u) {
return sum(d, u) * (u + 1) - sum(id, u);
}
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> w[i];
int t = w[i] - w[i - 1];
add(d, i, t);
add(id, i, i * t);
}
while (m--) {
char op;
int l, r, x;
cin >> op >> l >> r;
if (op == 'Q') cout << summ(r) - summ(l - 1) << endl;
else {
cin >> x;
add(d, l, x), add(d, r + 1, -x);
add(id, l, l * x), add(id, r + 1, (-x) * (r + 1));
}
}
return 0;
}

浙公网安备 33010602011771号