码迷,mamicode.com
首页 > 编程语言 > 详细

浅见树状数组

时间:2019-08-25 12:19:37      阅读:68      评论:0      收藏:0      [点我收藏+]

标签:owb   操作   时间   除了   code   height   维护   amp   str   

基本思想

根据任意正整数都可以被关于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)

拓展

区间修改 区间和查询

技术图片

代码

技术图片

 

浅见树状数组

标签:owb   操作   时间   除了   code   height   维护   amp   str   

原文地址:https://www.cnblogs.com/-sheldon/p/11407293.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!