芬威克树
一个<年代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
类