浅见树状数组

基本思想

根据任意正整数都可以被关于2的不重复次幂的唯一分解性质,若一个正整数x被分为10101,其中等于1的位是0,2,4,所以x可以被分解为2^4 + 2 ^ 2 + 2 ^ 0,进一步,区间为[1, x]的序列可以分成log(x)个小区间:

1 长度为2 ^ 4的[1, 2 ^ 4];

2长度为2 ^ 2的[2 ^ 4 + 1, 2 ^4 + 2 ^ 2];

3长度为2 ^ 0的[2 ^4 + 2 ^ 2 + 1, 2 ^4 + 2 ^ 2 + 2 ^ 0];

树状数组就是一种基于上述思想的一种数据结构,基本用途就是维护前缀和,将x长的序列分成log(x)个区间,更快

基本算法

由上文可知,若区间结尾为r, 那么区间的长度为r在二进制拆分下最小的2的正整数次幂,我们设为lowbit(r).

对于给定的一个序列a,我们设一个数组c,c[x]保存a的序列[x - lowbit(x) + 1, x]中的所有数的和

下图为树状数组的树形结构

 

该结构满足以下性质::

1 每个节点c[x]保存以他为根的所有子树的所有叶节点的和

2每个节点c[x]的长度为lowbit(x)

3除了树根,每个节点c[x]的父节点就是c[x + lowbit(x)]

4树的深度为log(x)

求lowbit

lowbit(n)表示的是n在二进制下最低的1以及他后面的0构成的数值,那么怎么求呢???

我们来看,一个数的二进制位10001100, 我们可以用他来按位与100,这样我们就可以得到了

首先,我们把它取反,此时数就变成了01110011, 我们将他加1,变成了01110100,这样我们就会发现,我们将n&100 == n&01110100,是不是就可以了?

所以为n&(~n + 1),可不可以在简单一下???

当然可以 在二进制补码下~n  = -1 -n,将他带入我们就得到了-n,所以lowbit(x) = x & -x

 

对某个元素进行加法操作

树状数组支持单点操作,对于单点加法,我们维护的是前缀和,所以我们只要将x及x以后的c数组加上y就可以了!

代码如下:

 

 查询前缀和

树状数组支持查询前缀和,即序列A第1~x数的和。

自己理解吧,时间复杂度为O(logN),代码如下:

统计x-y的值为:sum(y) - sum(x - 1)

拓展

区间修改 区间和查询

代码

 

转载于:https://www.cnblogs.com/-sheldon/p/11407293.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值