树状数组(Binary Indexed Tree,BIT),也称作 Fenwick 树,是一种用于高效处理动态数组前缀和查询及单点更新的数据结构。
以下是一个简单的树状数组的 C++ 实现:
#include <vector>
class FenwickTree {
private:
std::vector<int> tree;
public:
FenwickTree(int n) : tree(n + 1, 0) {}
// 单点更新:将索引 i 处的值增加 delta
void update(int i, int delta) {
while (i < tree.size()) {
tree[i] += delta;
i += i & -i; // 更新下一个节点的索引
}
}
// 查询前缀和:返回索引 1 到 i 的前缀和
int query(int i) {
int sum = 0;
while (i > 0) {
sum += tree[i];
i -= i & -i; // 移动到上一个节点的索引
}
return sum;
}
// 查询区间和:返回区间 [left, right] 的和
int rangeQuery(int left, int right) {
return query(right) - query(left - 1);
}
};
int main() {
std::vector<int> nums = {1, 3, 5, 7, 9, 11};
FenwickTree ft(nums.size());
// 将数组中的元素依次加入树状数组
for (int i = 0; i < nums.size(); ++i) {
ft.update(i + 1, nums[i]);
}
// 查询前缀和和区间和
std::cout << "Prefix sum of first 3 elements: " << ft.query(3) << std::endl;
std::cout << "Range sum from index 2 to 5: " << ft.rangeQuery(2, 5) << std::endl;
return 0;
}
在这个示例中,我们定义了一个 FenwickTree 类来实现树状数组。构造函数初始化了树状数组的大小,并将数组全部初始化为 0。update() 函数用于更新树状数组中的值,它从索引 i 开始,依次向后更新直到数组末尾,更新的方式是增加 delta。query() 函数用于查询索引 i 处的前缀和,它从索引 i 开始,依次向前查询直到索引为 0,返回查询结果的累加和。rangeQuery() 函数用于查询区间和,它通过计算两次前缀和的差来得到区间和的结果。