树状数组BIT

BIT

  • 树状数组或二叉索引树,全称 Binary Indexed Tree。本质就是用数组模拟树形结构,时间复杂度\(O(log_2n)\)
  • 线段树也能实现树状数组功能。树状数组的复杂度和线段树同级,但代码量更为简洁。

1 问题引入

  • 一个长度为n的数组,要求如下两个操作
    • 对第i个数加k,复杂度为\(O(1)\)
    • 对区间[1,i]求和,复杂度为\(O(n)\)
  • 当对此修改与查询,最坏为\(O(n^2)\)。当数据量很大时是难以接受的。
  • 而树状数组单点更新与区间查询都为\(O(log_2n)\),可以大大降低复杂度。
  • 总结一下,当某点经常更新,且要用到前缀和时可以使用树状数组,来降低复杂度。

2 树状数组

  • 树状数组是一种可以动态维护序列前缀和的数据结构,它的基本功能是:
    • 单点更新 update(i, v): 把序列 i 位置的数加上一个值 v,\(O(log_2n)\)
    • 区间查询 query(i): 查询序列[1⋯i] 区间的区间和,即 i 位置的前缀和,\(O(log_2n)\)
  • 如图所示,树状数组C存储的是对数组A各个位置的前缀和。
    BIT
    • C[1] = A[1]
    • C[2] = A[1] + A[2]
    • C[3] = A[3]
    • C[4] = A[1] + A[2] + C[3] + A[4]
    • ……
    • C[7] = A[7]
    • C[8] = A[1] + A[2] + C[3] + A[4] + A[5] + A[6] + A[7] + A[8]

2.1 lowbit()操作

  • 树状数组的前缀和,被分成了不同区间的和。与动态规划中的存储之前计算过的值来降低复杂度一样,树状数组也是用之前的区间值来累加,避免重复计算。
// 求最低位二进制为1的数
// 10100  ->  00100 = 4
// 01110  ->  00010  = 2
// 原码&
double lowbit(double x){
    return x&(-x);
}
  • 正数的原码、反码、补码相同,负数等于反码+1。通过x&(-x)可以只保留最低位为1的数。
    • 如原码10100变反码01011,反码01011再加1等于01100,最终相与得 00100

2.2 query()操作

  • 树状数组C[X]等于 [X-lowbit(X)+1,X] 中所有值的和。
  • 当要求X的前缀和时,query(X)= C[X] + C[X-lowbit(X)]+...
    • 直到 X = 0
int query(int x) 
{
    int ret = 0;
    while (x) {
        ret += C[x];
        x -= lowbit(x);
    }
    return ret;
}

2.3 update() 操作

  • 当对该点更新时,需要对其父结点同步更新
    • 如当A[6]更新时,需要更新后面的C[6]、C[8]等。
void update(int x) {
        while (x <= n) {
            ++C[x];
            x += lowbit(x);
        }
    }
BIT.cpp
class BIT {
private:
    vector<int> tree;
    int n;

public:
    BIT(int _n): n(_n), tree(_n + 1) {}

    static int lowbit(int x) {
        return x & (-x);
    }

    int query(int x) {
        int ret = 0;
        while (x) {
            ret += tree[x];
            x -= lowbit(x);
        }
        return ret;
    }

    void update(int x,int v=1) {
        while (x <= n) {
            tree[x] += v;
            x += lowbit(x);
        }
    }
};

3 应用

  • 树状数组与逆序对
  • ...

参考资料:
https://www.bilibili.com/video/BV1xq4y1i7et
https://blog.csdn.net/qq_40941722/article/details/104406126
https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/

posted @ 2022-04-30 21:41  Oniisan_Rui  阅读(51)  评论(0)    收藏  举报