树状数组 朱雀 2022-08-10 10:53 271阅读 0赞 1、概述 树状数组(binary indexed tree),是一种设计新颖的数组结构,它能够高效地获取数组中连续n个数的和。概括说,树状数组通常用于解决以下问题:数组\{a\}中的元素可能不断地被修改,怎样才能快速地获取连续几个数的和? 2、树状数组基本操作 传统数组(共n个元素)的元素修改和连续元素求和的复杂度分别为O(1)和O(n)。树状数组通过将线性结构转换成伪树状结构(线性结构只能逐个扫描元素,而树状结构可以实现跳跃式扫描),使得修改和求和复杂度均为O(lgn),大大提高了整体效率。 给定序列(数列)A,我们设一个数组C满足 C\[i\] = A\[i–2^k+ 1\] + … + A\[i\] 其中,k为i在二进制下末尾0的个数,i从1开始算! 则我们称C为树状数组。 下面的问题是,给定i,如何求2^k? 答案很简单:2^k=i&(i^(i-1)) ,也就是i&(-i) 下面进行解释: > 以i=6为例(注意:a\_x表示数字a是x进制表示形式): > > (i)\_10 = (0110)\_2 > > (i-1)\_10=(0101)\_2 > > i xor (i-1) =(0011)\_2 > > i and (i xor (i-1)) =(0010)\_2 > > 2^k = 2 > > C\[6\] = C\[6-2+1\]+…+A\[6\]=A\[5\]+A\[6\] 数组C的具体含义如下图所示: ![binary\_indexed\_tree2][binary_indexed_tree2] 当我们修改A\[i\]的值时,可以从C\[i\]往根节点一路上溯,调整这条路上的所有C\[\]即可,这个操作的复杂度在最坏情况下就是树的高度即O(logn)。另外,对于求数列的前n项和,只需找到n以前的所有最大子树,把其根节点的C加起来即可。不难发现,这些子树的数目是n在二进制时1的个数,或者说是把n展开成2的幂方和时的项数,因此,求和操作的复杂度也是O(logn)。 树状数组能快速求任意区间的和:A\[i\] + A\[i+1\] + … + A\[j\],设sum(k) = A\[1\]+A\[2\]+…+A\[k\],则A\[i\] + A\[i+1\] + … + A\[j\] = sum(j)-sum(i-1)。 下面给出树状数组的C语言实现: //求2^k int lowbit(int t) { return t & ( t ^ ( t - 1 ) ); } //求前n项和 int sum(int end) { int sum = 0; while(end > 0) { sum += in[end]; end -= lowbit(end); } return sum; } //增加某个元素的大小 void plus(int pos, int num) { while(pos <= n) { in[pos] += num; pos += lowbit(pos); } } 3、扩展——二维树状数组 一维树状数组很容易扩展到二维,二维树状数组如下所示: C\[x\]\[y\] = sum(A\[i\]\[j\]) 其中,x-lowbit\[x\]+1 <= i<=x且y-lowbit\[y\]+1 <= j <=y 4、应用 (1) 一维树状数组: 参见:[http://hi.baidu.com/lilu03555/blog/item/4118f04429739580b3b7dc74.html][http_hi.baidu.com_lilu03555_blog_item_4118f04429739580b3b7dc74.html] (2) 二维树状数组: 一个由数字构成的大矩阵,能进行两种操作 1) 对矩阵里的某个数加上一个整数(可正可负) 2) 查询某个子矩阵里所有数字的和 要求对每次查询,输出结果 5、总结 树状数组最初是在设计压缩算法时发现的(见参考资料1),现在也会经常用语维护子序列和。它与线段树(具体见:[数据结构之线段树][Link 1])比较在思想上类似,比线段树节省空间且编程复杂度低,但使用范围比线段树小(如查询每个区间最小值问题)。 6、参考资料 (1) Binary Indexed Trees: [http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=binaryIndexedTrees][http_www.topcoder.com_tc_module_Static_d1_tutorials_d2_binaryIndexedTrees] (2) 吴豪文章《树状数组》: [http://www.java3z.com/cwbwebhome/article/article19/zip/treearray.zip][http_www.java3z.com_cwbwebhome_article_article19_zip_treearray.zip] (3) 郭炜文章《线段树和树状数组》: [http://poj.org/summerschool/1\_interval\_tree.pdf][http_poj.org_summerschool_1_interval_tree.pdf] [binary_indexed_tree2]: http://dongxicheng.org/wp-content/uploads/2011/04/binary_indexed_tree2.jpg [http_hi.baidu.com_lilu03555_blog_item_4118f04429739580b3b7dc74.html]: http://hi.baidu.com/lilu03555/blog/item/4118f04429739580b3b7dc74.html [Link 1]: http://dongxicheng.org/structure/segment-tree/ [http_www.topcoder.com_tc_module_Static_d1_tutorials_d2_binaryIndexedTrees]: http://www.topcoder.com/tc?module=Static&d1=tutorials&d2=binaryIndexedTrees [http_www.java3z.com_cwbwebhome_article_article19_zip_treearray.zip]: http://www.java3z.com/cwbwebhome/article/article19/zip/treearray.zip [http_poj.org_summerschool_1_interval_tree.pdf]: http://poj.org/summerschool/1_interval_tree.pdf
相关 树状数组 详细介绍:[https://www.cnblogs.com/xenny/p/9739600.html][https_www.cnblogs.com_xenny_p_973960 我不是女神ヾ/ 2023年08月17日 16:26/ 0 赞/ 130 阅读
相关 树状数组 目录: 1. 概念 2. 应用 3. 充分性 4. 建立树状数组 5. 典题分析 一.概念 数组来模拟树形结构。那么、为什么不直接建树?没必要,因为树 秒速五厘米/ 2023年02月25日 11:29/ 0 赞/ 38 阅读
相关 树状数组 1、概述 树状数组(binary indexed tree),是一种设计新颖的数组结构,它能够高效地获取数组中连续n个数的和。概括说,树状数组通常用于解决以下问题:数组\{a 朱雀/ 2022年08月10日 10:53/ 0 赞/ 272 阅读
相关 树状数组 树状数组 树状数组:用线性数据结构的方法解决动态统计子树权和的问题。 类似于线段树,将区间分成小段,方便计算权和。 举个栗子,将a数组构造成树状数组c。 如果a 忘是亡心i/ 2022年07月26日 08:44/ 0 赞/ 256 阅读
相关 详解--树状数组 写下这个标题,其实心里还是没底的,与其说是写博帖,不如说是做总结。第一个接触树状数组还是两年前,用什么语言来形容当时的感觉呢?……太神奇了!真的,无法表达出那种感觉 淡淡的烟草味﹌/ 2022年06月10日 03:24/ 0 赞/ 238 阅读
相关 树状数组初探 前言 在前一篇文章:[线段树初探][Link 1] 中我们看了一下线段树的基本思想并且知道了线段树擅长于解决区间问题。其实对于某些区间问题,我们不仅可以用线段树解决,还可 古城微笑少年丶/ 2022年05月30日 03:22/ 0 赞/ 205 阅读
相关 树状数组 树状数组单点修改,单点查询 洛谷oj :[点我][Link 1] 模板: include<iostream> include<cstdio> 心已赠人/ 2022年05月16日 05:17/ 0 赞/ 300 阅读
相关 树状数组实现 树状数组能够完成如下操作: 给一个序列a0-an 计算前i项和 对某个值加x 时间o(logn) 注意:有人觉得前缀和就行了,但是你还要维护啊,改变某个值,一个一个改 叁歲伎倆/ 2022年05月12日 02:44/ 0 赞/ 192 阅读
相关 树状数组板子 树状数组 重点是在树状的数组 大家都知道二叉树吧 叶子结点代表A数组A\[1\]~A\[8\] ![786945-20161206222443741-120171603 r囧r小猫/ 2022年03月15日 15:22/ 0 赞/ 303 阅读
相关 树状数组模板 //树状数组 struct Bit { vector<int> a; int sz; void ini ゞ 浴缸里的玫瑰/ 2021年09月19日 05:46/ 0 赞/ 378 阅读
还没有评论,来说两句吧...