# **树状数组(BIT)**
## **概述**
树状数组是一个可以用来解决单点更新和区间查询的数据结构,其复杂度为log2(n),原则上来说,能用树状数组解决的问题就能用线段树解决,能用线段树解决的不一定能用树状数组来解决,那么我们为什么还要学习树状数组呢?因为它写起来短啊!而且不容易出错QAQ。
## **树状数组的操作** ##
* ### **树状数组的构造** ###
对于一个数组A,我们需要一个辅助数组C来进行构造树状数组。树状数组的模样就是这样:
![](https://box.kancloud.cn/3e0263d955afe2e0a6fc458018985612_1219x470.png)
其中:
```
C[1]=A[1]
C[2]=A[1]+A[2]
C[3]=A[3]
C[4]=A[1]+A[2]+A[3]+A[4]
C[5]=A[5]
C[6]=A[5]+A[6]
C[7]=A[7]
C[8]=A[1]+A[2]+A[3]+A[4]+A[5]+A[6]+A[7]+A[8]
```
将下标转化为二进制可得:
```
C[1] = C[0001] = A[1];
C[2] = C[0010] = A[1]+A[2];
C[3] = C[0011] = A[3];
C[4] = C[0100] = A[1]+A[2]+A[3]+A[4];
C[5] = C[0101] = A[5];
C[6] = C[0110] = A[5]+A[6];
C[7] = C[0111] = A[7];
C[8] = C[1000] = A[1]+A[2]+A[3]+A[4]+A[5]+A[6]+A[7]+A[8];
```
不难发现
```
C[i]=A[i-2^k+1]+A[i-2^k+2]+......A[i]
```
其中k为i的二进制从最低位到最高位连续的0
的个数。这个时候我们就要用到我们的lowbit操作了。
```
int lowbit(int x){
return x&(-x)
}
```
lowbit(x)所得到的就是2^k。
这样当我们学会了lowbit操作时。我们就可以进行单点更新和区间查询了。
* ### **单点更新**
参照上图,假如我们要对A[1]进行加k操作,那么我们需要更新的C数组就该是:
```
1 C[1]+=k
1+lowbit(1)=2 C[2]+=k
2+lowbit(2)=4 C[4]+=k
4+lowbit(4)=8 C[8]+=k
end
```
这样用代码表示即为:
```
void update(int id,int k){
for(int i=id;i<=n;i+=lowbit(i)) C[i]+=k;
}
```
* ### **区间查询**
- 简介
- 零基础快速入门ACM
- C语言快速入门
- C语言快速入门
- C/C++基础
- 输入输出
- 数组和字符串
- 数组
- 字符数组
- 函数和递归
- C++标准容器库(STL)
- Vector
- Map
- Set
- String
- Stack
- Queue
- Priority_queue
- 贪心
- 硬币问题
- 区间调度问题
- 字典序最小问题
- 独木舟问题
- 搜索
- DFS
- BFS
- 剪枝
- 记忆化搜索
- 常用技巧
- 倍增
- 高精度
- 大数加法
- 大数减法
- 大数乘法
- 大数除法
- 大数阶乘
- 输入挂
- 前缀和
- 二分
- 本地预处理
- 尺取
- 枚举
- 坐标离散化
- 分治
- 数列分治
- 树上分治
- 平面分治
- 计算几何
- 凸包
- 点积
- 叉积
- 线段关系
- 皮克定理
- 最近点对
- 数据结构
- 线段树
- 树状数组
- 并查集
- 动态规划
- 基础知识
- 信息学竞赛中的动态规划
- 动态规划初步
- 最长上升子序列(LIS)
- 最长公共子序列(LCS)
- 最大子段和
- 背包问题
- 部分背包
- 0 1 背包
- 完全背包
- 多重背包
- 背包的可行性问题
- 线性DP
- 树形DP
- 区间DP
- 数位DP
- 动态规划优化
- 字符串
- KMP算法
- 拓展KMP
- 字符串Hash
- Manacher算法
- 后缀数组
- Trie树
- 博弈论
- Nim博弈
- Bash博弈
- 斐波那契博弈
- 威佐夫博弈
- SG函数
- 数论
- 整数研究
- 素数判断
- 素数筛选
- 快速幂
- 算数基本定理
- 最大公约数(Gcd)
- 费马小定理
- 扩展欧几里得
- 逆元
- 同余定理
- 组合数学
- 容斥原理
- 抽屉原理
- 卢卡斯(Lucas)
- 卡特兰(Catalan)
- 著名函数
- 欧拉函数
- 莫比乌斯函数
- 线性代数
- 矩阵运算
- 矩阵快速幂
- 图论
- 存图方法
- 邻接矩阵
- 邻接表
- Vector存图
- 链式前向星
- 图的遍历
- 拓扑排序
- 最短路
- Dijkstra算法
- SPFA算法
- Floyed 算法
- 最小生成树
- Prim算法
- Kruskal算法
- 最近公共祖先 (LCA)
- 二分图匹配
- 网络流
- 其他
- 莫队