- OI Wiki
- 《算法笔记》
前言
利用大节点来存储小节点的信息。在查询或修改的时候直接利用大节点的信息,节省时间。
事实上,树状数组的代码要比线段树短得多,思维也更清晰,在解决一些单点修改的问题时,树状数组是不二之选。
lowbit运算
形式一
l o w b i t ( x ) = 2 m a x { i │ x m o d 2 i = 0 } lowbit(x) = 2^{max \{{i│x\mod 2^i=0\} }} lowbit(x)=2max{i│xmod2i=0}
能整除x的最大2的幂次
形式二
l o w b i t ( x ) = x & ( − x ) lowbit(x) = x \&(-x) lowbit(x)=x&(−x)
补码储存方式: − x -x −x相当于把 x x x二进制每一位取反,再+1,等价于把 x x x二进制最右边1的左边的每一位都取反。
那么KaTeX parse error: Expected '}', got '&' at position 9: x\text{ &̲ }(-x)就是x二进制最右边的1和右边的0。

树状数组
基本知识

假设我们大小节点之间的关系是求和。对于原数组 a,我们用新的树状数组 t 来辅助。
t i = a i , i = 1 , 3 , 5 , 7 t_i=a_i, i=1,3,5,7 ti=ai,i=1,3,5,7
t 2 = a 1 + a 2 , t 6 = a 5 + a 6 t_2=a_1+a_2, t_6=a_5+a_6 t2=a1+a2,t6=a5+a6
t 4 = a 1 + a 2 + a 3 + a 4 t_4=a_1+a_2+a_3+a_4 t4=a1+a2+a3+a4
t 8 = ∑ i = 1 8 a i t_8=\sum^8_{i=1} a_i t8=∑i=18ai
如果要查 a 1 → a 5 a_1→a_5 a1→a5的和,如果树状数组存储的是和,直接用 t 5 + t 4 t_5+t_4 t5+t4 即可。查 a 1 → a 7 a_1→a_7 a1→a7 的和,直接 t 7 + t 6 + t 4 t_7+t_6+t_4 t7+t6+t4 即可
那么我们主要要解决两个问题:
- 怎么知道某个点由哪几个点组成?
- 怎么修改和查询?
怎么知道某个点由哪几个点组成
对于编号为 x x x的某点,由 l o w b i t ( x ) lowbit(x) lowbit(x)个点组成
-
以 t [ 6 ] t[6] t[6]为例, l o w b i t ( 6 )