1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
| #include <iostream>
#include <vector>
using namespace std;
// 定义线段树的节点
struct Node {
int l, r; // 左右子节点的下标
int sum; // 区间和
};
vector<Node> tree; // 存储线段树的数组
// 构建线段树
void build(int l, int r, int index, vector<int>& nums) {
tree[index].l = l;
tree[index].r = r;
if (l == r) { // 叶子节点
tree[index].sum = nums[l];
return;
}
int mid = (l + r) / 2;
build(l, mid, index * 2, nums); // 构建左子树
build(mid + 1, r, index * 2 + 1, nums); // 构建右子树
tree[index].sum = tree[index * 2].sum + tree[index * 2 + 1].sum; // 计算区间和
}
// 区间查询
int query(int l, int r, int index) {
if (tree[index].l >= l && tree[index].r <= r) { // 当前区间完全包含在查询区间内
return tree[index].sum;
}
int mid = (tree[index].l + tree[index].r) / 2;
int sum = 0;
if (l <= mid) { // 查询区间和左子树有交集
sum += query(l, r, index * 2);
}
if (r > mid) { // 查询区间和右子树有交集
sum += query(l, r, index * 2 + 1);
}
return sum;
}
// 单点修改
void update(int pos, int val, int index) {
if (tree[index].l == tree[index].r) { // 叶子节点
tree[index].sum = val;
return;
}
int mid = (tree[index].l + tree[index].r) / 2;
if (pos <= mid) { // 修改的位置在左子树
update(pos, val, index * 2);
} else { // 修改的位置在右子树
update(pos, val, index * 2 + 1);
}
tree[index].sum = tree[index * 2].sum + tree[index * 2 + 1].sum; // 更新区间和
}
int main() {
vector<int> nums = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 原始数组
int n = nums.size(); // 数组长度
tree.resize(n * 4); // 线段树的大小为 4n
build(0, n - 1, 1, nums); // 构建线段树
cout << query(0, 4, 1) << endl; // 查询区间 [0, 4] 的和
update(2, 10, 1); // 将第 2 个元素修改为 10
cout << query(0, 4, 1) << endl; // 查询区间 [0, 4] 的和
return 0;
}
|