用于单点更新、区间查询
树状数组有两个操作:单点更新、区间查询
空间复杂度O(n),单点更新、区间查询时间均为log(n)
对于二维的区间来讲,我们可以使用二维树状数组
个人理解
蓝书翻到P196看图
- 更新过程
从11(1011)开始向上爬,作为右子树每次计算父节点(i-=lowbit(i))
至于为何每次减少lowbit(i),是因为子树的白条长度正好为lowbit(i)
11(1011) -> 10(1010) -> 8(1000) -> 0 - 查询过程
从3(0011)开始向上爬,作为左子树每次计算父节点(i+=lowbit(i))
至于为何每次增加lowbit(i),是因为子树的白条长度正好为lowbit(i),而父节点白条长度正好为lowbit(i)×2
3(0011) -> 4(0100) -> 8(1000) -> Max
模板
#define lowbit(x) ((x)&(-x))
int n, arr[int(5e4)+5];
long long getsum(int idx){
long long sum=0;
for (int i=idx; i>0; i-=lowbit(i))
sum+=arr[i];
return sum;
}
void add(int idx, int num){
for (int i=idx; i<=n; i+=lowbit(i))
arr[i]+=num;
}
注意
- 查询区间是[1, MAX]
不是[0, MAX-1]啊,总是分不清。。。
0是不可能算的,所有值的查找都包括了0,所以不能算啊
所以说看了蓝书的图就没有问题了,0是一个类似终点的“节点”