线段树是一种非常强大的数据结构,用于解决区间查询和更新问题。它允许你对一个数组的子区间执行各种操作,如求和、求最小值、求最大值等。以下是一个C++模板,展示了如何实现线段树。
#include <iostream>
#include <vector>
#include <algorithm>
// 线段树的实现
template<typename T>
class SegmentTree {
private:
std::vector<T> tree; // 线段树的数组表示
int n; // 数组的大小
// 合并两个元素,可以是求和、求最大值等
T merge(T a, T b) {
return a + b; // 示例使用求和
}
// 构建线段树
void build(int node, int start, int end, const std::vector<T>& arr) {
if (start == end) {
tree[node] = arr[start];
} else {
int mid = (start + end) / 2;
build(2 * node, start, mid, arr);
build(2 * node + 1, mid + 1, end, arr);
tree[node] = merge(tree[2 * node], tree[2 * node + 1]);
}
}
// 区间查询
T query(int node, int start, int end, int l, int r) {
if (r < start || end < l) {
return 0; // 返回一个合适的默认值,例如求和为0
}
if (l <= start && end <= r) {
return tree[node];
}
int mid = (start + end) / 2;
T left_result = query(2 * node, start, mid, l, r);
T right_result = query(2 * node + 1, mid + 1, end, l, r);
return merge(left_result, right_result);
}
// 点更新
void update(int node, int start, int end, int idx, T val) {
if (start == end) {
tree[node] = val;
} else {
int mid = (start + end) / 2;
if (idx <= mid) {
update(2 * node, start, mid, idx, val);
} else {
update(2 * node + 1, mid + 1, end, idx, val);
}
tree[node] = merge(tree[2 * node], tree[2 * node + 1]);
}
}
public:
// 构造函数,接收一个数组作为输入,建立线段树
SegmentTree(const std::vector<T>& arr) {
n = arr.size();
tree.resize(4 * n);
build(1, 0, n - 1, arr);
}
// 查询区间[l, r]的结果
T query(int l, int r) {
return query(1, 0, n - 1, l, r);
}
// 更新位置idx的值为val
void update(int idx, T val) {
update(1, 0, n - 1, idx, val);
}
};
int main() {
// 示例用法
std::vector<int> arr = {1, 3, 5, 7, 9, 11};
SegmentTree<int> st(arr);
std::cout << "Sum in range [1, 3]: " << st.query(1, 3) << std::endl;
st.update(1, 10); // 将arr[1]更新为10
std::cout << "Sum in range [1, 3] after update: " << st.query(1, 3) << std::endl;
return 0;
}
在这个模板中,我们使用一个数组tree
来表示线段树。每个节点node
表示区间[start, end]
的合并结果。对于求和操作,merge
函数返回两个子区间的和;对于求最大值或最小值操作,merge
函数返回相应的最大或最小值。
构造函数SegmentTree
接受一个数组作为输入,然后调用build
函数来递归地构建线段树。
query
函数用于查询区间[l, r]
的合并结果。如果查询区间完全在当前节点的代表区间内部,我们直接返回该节点的值。如果查询区间与当前节点的代表区间相交,我们递归地查询两个子节点,并将结果合并后返回。
update
函数用于更新数组中某个位置的值。我们首先更新叶节点的值,然后递归地更新父节点的值,直到根节点。
请注意,这个模板假设数组是从0开始索引的。如果你的数组是从1开始索引的,你可能需要对代码进行一定的调整。此外,根据你的具体需求,你可能需要修改merge
函数来执行不同的操作。