芬威克树
一个<年代trong>芬威克树
前缀的金额
的<年代pan class="katex">
这个想法也被称为<年代trong>部分和
正整数的前缀和是多少?
它们是如下图所示的三角形数字。
天真的方法
最简单的计算方法<年代pan class="katex">
动机
假设我们有一个16个元素的数组,它组成了以下二叉树的叶子: 让我们假设父节点包含整个树中所有子节点的和。这意味着根节点拥有数组中所有元素的和。 核心思想:
这些叶子的标签从0000到1111。
算法示意图
这部分可能很难,除非你有<一个target="_blank" rel="nofollow" href="//www.parkandroid.com/wiki/fenwick-tree/">直觉
.
为了简单起见,我们假设使用的是基于1的数组。 这是芬威克树的阵列 我们已经看到了数据结构背后的动机。现在,我们需要看看如何构建、更新和查询它。 增加了<年代pan class="katex">
正如前面讨论的,这是运行的<年代pan class="katex">
更新
位操作技巧
幸运的巧合是,计算机内部使用二进制系统来表示整数,这给我们带来了一个非常有趣的位操作技巧,使我们很容易实现上述算法。 注意,我们经常需要将整数表示为2的幂,并且通常在上述算法中使用最低的幂。最低次幂实际上是整数的最后一个集合位。
显然,我们可以编写一个循环来找到它,但事实证明有一个更好(更简单)的方法来做到这一点。事实证明 让我们对12做同样的计算。 我们有<年代pan class="katex">
这应该适用于任何整数。这里有一个概括 2的最高幂,即不超过 假设<年代pan class="katex">
是二进制表示的整数吗<年代pan class="katex">
现在,的补码<年代pan class="katex">
是<年代pan class="katex">
因此,<年代pan class="katex">
这里,最后一个设置位的位值是<年代pan class="katex">
实现
实现很简单,只是使用基于1的数组很容易被错误处理。 Python:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16
类