How to adapt Fenwick tree to answer range minimum queries

前端 未结 2 962
小蘑菇
小蘑菇 2021-02-01 08:09

Fenwick tree is a data-structure that gives an efficient way to answer to main queries:

  • add an element to a particular index of an array update(index, value)
2条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-02-01 08:32

    The Fenwick tree structure works for addition because addition is invertible. It doesn't work for minimum, because as soon as you have a cell that's supposed to be the minimum of two or more inputs, you've lost information potentially.

    If you're willing to double your storage requirements, you can support RMQ with a segment tree that is constructed implicitly, like a binary heap. For an RMQ with n values, store the n values at locations [n, 2n) of an array. Locations [1, n) are aggregates, with the formula A(k) = min(A(2k), A(2k+1)). Location 2n is an infinite sentinel. The update routine should look something like this.

    def update(n, a, i, x):  # value[i] = x
        i += n
        a[i] = x
        # update the aggregates
        while i > 1:
            i //= 2
            a[i] = min(a[2*i], a[2*i+1])
    

    The multiplies and divides here can be replaced by shifts for efficiency.

    The RMQ pseudocode is more delicate. Here's another untested and unoptimized routine.

    def rmq(n, a, i, j):  # min(value[i:j])
        i += n
        j += n
        x = inf
        while i < j:
            if i%2 == 0:
                i //= 2
            else:
                x = min(x, a[i])
                i = i//2 + 1
            if j%2 == 0:
                j //= 2
            else:
                x = min(x, a[j-1])
                j //= 2
        return x
    

提交回复
热议问题