使用二进制索引树进行范围更新+范围查询


10

我试图了解如何修改二进制索引树(fenwick树)以处理范围查询和范围更新。

我发现以下来源:

http://kartikkukreja.wordpress.com/2013/12/02/range-updates-with-bit-fenwick-tree/ http://programmingcontests.quora.com/Tutorial-Range-Updates-in-Fenwick-Tree http ://apps.topcoder.com/forums/?module = Thread&threadID = 756271&start = 0&mc = 4#1579597

但是即使通读了所有它们,我也无法理解第二个二进制索引树的目的或作用。

有人可以向我解释一下如何修改二进制索引树来处理这些吗?

Answers:


9

假设您有一个空数组:

0  0  0  0  0  0  0  0  0  0  (array)
0  0  0  0  0  0  0  0  0  0  (cumulative sums)

您想将范围更新为+5到[3..7]:

0  0  0  5  5  5  5  5  0  0  (array)
0  0  0  5 10 15 20 25 25 25  (desired cumulative sums)

如何使用2个二值索引树存储所需的累积总和?

诀窍是使用两个二进制索引树BIT1和BIT2,它们的累加总和是根据它们的内容来计算的。在此示例中,这是我们在两棵树中存储的内容:

0   0   0   5   5   5   5   5   0   0  (BIT1)
0   0   0  10  10  10  10  10 -25 -25  (BIT2)

要查找sum[i],您可以计算出以下内容:

sum[i] = BIT1[i] * i - BIT2[i]

例如:

sum[2] = 0*2 - 0 = 0
sum[3] = 5*3 - 10 = 5
sum[4] = 5*4 - 10 = 10
...
sum[7] = 5*7 - 10 = 25
sum[8] = 0*8 - (-25) = 25
sum[9] = 0*9 - (-25) = 25

为了实现先前范围更新的期望BIT1和BIT2值,我们进行了3次范围更新:

  • 我们需要将BIT1的范围更新为+5到索引3..7。

  • 我们需要将BIT2的范围更新为+10到索引3..7。

  • 我们需要将BIT2的范围更新为-25到索引8..9。

现在让我们再进行一次转换。实际上,我们没有存储上面显示的BIT1和BIT2的值,而是存储了它们的累加和。这使我们可以通过对累积总和进行4次更新来进行上述3次范围更新:

BIT1sum[3] += 5
BIT1sum[8] -= 5
BIT2sum[3] += 10
BIT2sum[8] -= 35

通常,将值v添加到range [i..j]的算法为:

BIT1sum[i]   += v
BIT1sum[j+1] -= v
BIT2sum[i]   += v * (i-1)
BIT2sum[j+1] -= v * j

其中+ =和-=语法仅表示用该索引处的正值或负值更新BIT累积和数据结构。请注意,在更新索引处的BIT累积总和时,它将隐式影响该索引右边的所有索引。例如:

0 0 0 0 0 0 0 0 0 0 (original)

BITsum[3] += 5

0 0 0 5 5 5 5 5 5 5 (after updating [3])

BITsum[8] -= 5

0 0 0 5 5 5 5 5 0 0 (after updating [8])

O(logn)


您创建BIT2然后拥有的最初动机是sum[i] = BIT1[i] * i - BIT2[i]什么?似乎可行,但似乎太武断了……有什么见识可以使您对此有所了解?
1110101001 2014年

3
好吧,我没有发明这种算法。我读的就像你一样。但要注意的一件事是,当您添加范围更新时,您的累计总和将成为递增的顺序(5、10、15、20等)。BIT不存储那样的递增序列。但是,如果您在BIT中存储一个常数(5),然后将BIT值乘以索引,您将获得所需的递增序列。但是,您需要修正序列的开头和结尾。那就是第二棵树的目的。
JS1 2014年

总体来说不错,但是我发现您写了“我们没有存储上面显示的BIT1和BIT2的值,而是存储了它们的累加总和”,这使我感到困惑,我想您实际上是在做相反的事情,即存储增量
j_random_hacker 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.