68/300
- 区域和检索 - 数组可修改
给定一个整数数组 nums,求出数组从索引 i 到 j (i ≤ j) 范围内元素的总和,包含 i, j 两点。
update(i, val) 函数可以通过将下标为 i 的数值更新为 val,从而对数列进行修改。
示例:
Given nums = [1, 3, 5]
sumRange(0, 2) -> 9
update(1, 2)
sumRange(0, 2) -> 8
说明:
数组仅可以在 update 函数下进行修改。
你可以假设 update 函数与 sumRange 函数的调用次数是均匀分布的。
有update,使用 binary indexed tree(BIT)/ fenwick tree
303 区域和检索 - 数组不可变&304 二维区域和检索 - 矩阵不可变都是用的dp,存前面所有range的和,
而bit就是存部分range的和,一旦遇到update,就不需要迁一发动全身啦,而是动部分身,像这样:
说白了,就是每个节点都有一个管控范围:
为了构建这样的效果,我们需要用到二进制(起始位置从20开始,而不是从0开始)。
来看1+2+3+…+16 = 136 如何用BIT储存:
这样的tree我们是如何建立的?
移动都是一个一个的,十进制的步长是1,二进制的步长是整串数最右的1
譬如,
十进制的6,下一个是6+1 = 7
二进制的6,表示为(0110)2,找到最右边的1,也就是(0010)2,
(0110)2+(0010)2=(1000)2,相当于十进制的8,看上图,6的下一个节点是8
同理,二进制的4和7,下个节点也都是8
节点8的值就是4,6,7三个节点的和。
当树建好后,我们要问问题了,前8个数的和是多少?
这时候要往前看,看节点8之前还有没有不在它的管控范围下的节点
8: (1000)2 - (1000)2 = 0,也就是节点8自己的值就够了
按此(超出控制范围的节点)重新构造树,