【C++】树状数组
创始人
2024-06-02 12:23:46

定义:

所谓树状数组,逻辑结构是一棵树,但是采用数组实现,他能解决单点修改区间查询类的问题,属于前缀和的一种优化。

lowbit:

学习树状数组,首先要引入lowbit 概念,所谓 lowbit,指的是二进制数最低位的1的权值,比如二进制数1100的lowbit就是二进制表示就是100,也就是权值为2^2 = 4,下文中我们用lowbit(x)表示x 的lowbit值。实际上,lowbit(x)= x&(−x),&表示按位与运算。

int lowbit(int x) {return (x & (-x));
}
#define lowbit(x) (x & (-x))

在c语言中,一个数的负数的二进制为该数字取反后加一(-x)等于(~x + 1),其中~符号表示为取反,如某个数的二进制为(10100100),则取反后为(01011011),再加一为(0101100),注意原码,反码,补码的含义。

原码:001010
反码:110101
补码:110110反码加一后为改数学负数的二进制表达形式

如     x : 1001010110

      ~x :  0110101001

~x + 1 :  0110101010,

从最低位到最高位,如果x的二进制形式下这个位置是0,则取反之后变成1,1 + 1就会往前进位,知道x的某一位为1时,进位结束.因此 lowbit (x):x的二进制形式下最低位的1的权值.

树状数组结构

在图中Ai表示原数组,Ci 表示Ai对应的树状数组。

Ci 维护的是 Ai的区间信息,那么 Ci究竟维护什么区间呢?我们可以先计算下lowbit(i).

lowbit(1)=1
lowbit(2)=2
lowbit(3)=1
lowbit(4)=1
lowbit(5)=1
lowbit(6)=2
lowbit(7)=1
lowbit(8)=8

我们可以发现,Ci 维护的长度就是 lowbit(i),维护区间是 [i−lowbit(i)+1,i]。

如C3维护的区间是[2−lowbit(2)+1,2]即[1,2],C8维护的区间是[8−lowbit(8)+1,8]即[1,8]。

那么树状数组的 Ci 可能会影响哪些位的值呢?以C1为例,1+lowbit(1)=2,2+lowbit(2)=4,4+lowbit(4)=8,我们发现第 i 个数值会递归影响所有的父结点,在树状数组中编号为i 的结点的父结点编号为 i+lowbit(i)。

 

相关内容

热门资讯

节能风电副总经理贾锐离任,年龄... 3月13日,节能风电公告,因工作调动,贾锐先生不再担任副总经理职务。资料显示,贾锐,男,1968年出...
赵乐际:在第十四届全国人民代表... 在第十四届全国人民代表大会第四次会议上的讲话(2026年3月12日)赵乐际各位代表:十四届全国人大四...
内幕交易!8人被抓! (来源:五道口江湖)香港证监会和廉政公署公布了昨天行动的详细内容,这次行动一共2天,3月10日和11...
风波中的“宇宙大所”盈科掌舵人... 融资担保风波爆发前,网络舆论场中流传更多的,是梅向荣早年励志的创业故事。1997年,月薪仅500元的...
两会世界观察|“中国发展规划法... 新华社北京3月12日电3月12日,十四届全国人大四次会议表决通过国家发展规划法,为在法治轨道上科学编...