树状数组BIT
BIT
- 树状数组或二叉索引树,全称 Binary Indexed Tree。本质就是用数组模拟树形结构,时间复杂度。
- 线段树也能实现树状数组功能。树状数组的复杂度和线段树同级,但代码量更为简洁。
1 问题引入
- 一个长度为n的数组,要求如下两个操作
- 对第i个数加k,复杂度为。
- 对区间[1,i]求和,复杂度为。
- 当对此修改与查询,最坏为。当数据量很大时是难以接受的。
- 而树状数组单点更新与区间查询都为,可以大大降低复杂度。
- 总结一下,当某点经常更新,且要用到前缀和时可以使用树状数组,来降低复杂度。
2 树状数组
- 树状数组是一种可以动态维护序列前缀和的数据结构,它的基本功能是:
- 单点更新 update(i, v): 把序列 i 位置的数加上一个值 v,
- 区间查询 query(i): 查询序列[1⋯i] 区间的区间和,即 i 位置的前缀和,
- 如图所示,树状数组C存储的是对数组A各个位置的前缀和。
- 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()操作
- 树状数组的前缀和,被分成了不同区间的和。与动态规划中的存储之前计算过的值来降低复杂度一样,树状数组也是用之前的区间值来累加,避免重复计算。
copy
- 1
- 2
- 3
- 4
- 5
- 6
- 7
// 求最低位二进制为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
copy
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
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]等。
copy
- 1
- 2
- 3
- 4
- 5
- 6
void update(int x) {
while (x <= n) {
++C[x];
x += lowbit(x);
}
}
BIT.cpp
copy
- 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
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/
本文作者:oniisan
本文链接:https://www.cnblogs.com/oniisan/p/BIT.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步