Fenwick Tree (Binary Indexed Tree)
Last updated
Was this helpful?
Last updated
Was this helpful?
陈老师说花三天时间研究明白这个没啥意义。不过我看了小半天就看完了。。也没啥难的嘛。。。
build O(n log n)
update O(log n)
query O(log n)
The two's complement of an N-bit number is defined as the complement with respect to 2^N; in other words, it is the result of subtracting the number from 2^N
和之前那道题一样,把 segment tree 改成 fenwick tree 的写法如下:
fenwick tree 可以用 array 存,纯靠 bit manipulation 操作。
tree 有一个 dummy root,所以对于单维度大小为 n 的输入,实际数组会在每一个维度 +1 的 padding.
因此在每次更新原数组 index 位置的数时,在树上实际的 update 位置是 index + 1.
树的 update 过程很像机器学习里面的 forward/backward propagation,每次更新之后先计算 diff,再把 diff 传导过去。因此 fenwick tree 有时候需要一个数组去保存所有值,用于计算 diff.
对于给定 index,树的 update 是一个 index 逐渐增加的过程,相对的,树的求和是个不断寻找 parent,index 逐渐减小的过程。
Fenwick Tree 在增加维度上的优势在这题中体现的非常好。
增加维度的逻辑非常简单,只需要把对应的 tree array 增加维度就可以了,这时候新的getSum(i,j)所代表的是,从 (0,0) 开始到 (i,j) 的矩形范围内的 sum,相对于一维 fenwick tree 中的 (0, index) 的和。
fenwick tree 本质上是树状的 prefix sum 数组,维度非常灵活,每一个位置上的getSum()都代表当前坐标到 origin 原点的 cumulative sum.
因此对于矩阵中任意矩形,都可以看做四个以原点为起点的矩形的相互覆盖,可以以同样的时间复杂度求解矩阵中任意位置任意形状的矩形和。