RMQ使用两个fenwick树(二进制索引树)

时间:2017-03-09 02:54:49

标签: algorithm data-structures fenwick-tree rmq binary-indexed-tree

基于此paper,我发现使用两个BIT在O(lg N)中执行RMQ非常棒,因为它比分段树更容易编码,并且该文件声称它表现更好也比其他数据结构。

我理解如何构建树以及如何进行查询操作,但我对更新操作感到困惑。这是引用:

  

我们进行以下观察:当我们生成相关的间隔时   我们经过的节点,我们可以从节点开始覆盖整个区间 [p + 1,y]   p + 1和攀爬第一棵树(图2.1)。因此,我们不是对每个节点进行查询   更新,我们通过爬树一次计算查询结果。

     

类似地,我们可以通过以下方式更新 [x,p - 1] 形式的所有间隔   节点p - 1和攀爬第二棵树(图2.2)。应用相同的算法   更新两棵树。

我怀疑它应该是相反的:为了找到最小间隔 [p + 1,y] ,我们应该使用第二棵树而不是第一棵树一;为了找到最小间隔 [x,p-1] ,我们应该使用第一棵树

我的问题是:我说错了吗?如果不是,有人可以给出一个简单的例子来演示更新操作的工作原理吗?

1 个答案:

答案 0 :(得分:1)

解释有点含糊不清。我猜他们的意思是[p+1,y]你从p+1开始攀登前三个,但是使用第二个树进行查询。

让我们假设您更新第10个索引的值(来自论文)。您必须回答[x, 10 - 1]&的查询更新树时[10 + 1, y]。为了有效地做到这一点,你需要建立两个“攀爬”列表:

CLB1攀爬p+1{11, 12}中的第一棵树,该树对应于下一个时间间隔:[11..11],第二棵树的[12..15]

CLB2攀爬p-1{9, 8}中的第二个树,该树对应于下一个时间间隔:[9..9][1..8]第一棵树

现在,您可以通过爬上从10开始的第一棵树来开始更新第一棵树。

10 - 微不足道的更新

12 - 您需要查询[9..9]{10}[11..11]{12}。您可以通过[9..9]的第一个成员从BIT1获得CLB2的答案。您可以通过[11..11]的第一个成员从BIT2获得CLB1的答案。 {10}{12}是微不足道的。

16 - 您需要查询[1..9]{10}[11..15](没有{16},因为它是虚构的)。通过前两项[1..9],您从BIT1开始CLB2。通过前两项[11..15],您从BIT2开始CLB1{10}是微不足道的。

正如您在左侧查询中看到的那样,您可以使用第二棵树的p-1中的攀爬历史从第一棵树中获取答案。对于正确的查询,您可以使用第一棵树的p+1的攀爬历史从第二棵树中获取答案。

类似的过程用于更新正确的树。

更新:第9个节点的流程

如果要更新第9个索引,我们有下一个CLB s:

CLB1{10, 12}[10..11]的间隔:[12..15]BIT2

CLB2{8},间隔时间[1..8] BIT1

更新BIT1

9 - 琐碎

10 - 琐碎(我们只需要{9}{10}

12 - 我们需要先从CLB1 - [10..11]进入,{12}进入{9}

16 - 我们需要来自CLB1 - [10..11] U [12..15]的两个第一个条目,CLB2的第一个条目 - [1..8]{9}

更新BIT2

9 - 琐碎

8 - 我们需要前两个来自CLB1 - [10..11] U [12..15]{9} {8}

的条目

0 - 我们需要前两个来自CLB1 - [10..11] U [12..15]的条目和来自CLB2的第一个条目 - [1..8]{9}