c++实现树状数组

156 阅读1分钟

树状数组(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 开始,依次向后更新直到数组末尾,更新的方式是增加 deltaquery() 函数用于查询索引 i 处的前缀和,它从索引 i 开始,依次向前查询直到索引为 0,返回查询结果的累加和。rangeQuery() 函数用于查询区间和,它通过计算两次前缀和的差来得到区间和的结果。