How to do a range update in Binary Indexed Tree or Fenwick Tree?

后端 未结 2 2142
礼貌的吻别
礼貌的吻别 2021-02-15 12:55

I am trying to solve this problem in UVA with Binary Indexed Tree:

Problem H
Ahoy, Pirates!

Input: Standard Input
Output: Standard Output


In the ancient pirate         


        
2条回答
  •  醉梦人生
    2021-02-15 13:12

    A binary indexed tree (aka Fenwick tree) is an efficient way of representing a frequency table in order to be able to quickly extract cumulative frequencies and uses N bins to hold N frequency values.

    However, for this problem I would recommend a segment tree instead. A segment tree has a similar structure to a binary indexed tree except it typically uses 2N bins instead.

    Fenwick tree

    As with the Fenwick tree, it is helpful to think about each node in the tree as being responsible for a set of indices. Here is an illustration of the responsibilities for nodes in a Fenwick tree of size 8:

    Index   Responsibilities
      8              8
      7        7     8
      6          6   8 
      5        5 6   8
      4            4 8
      3        3   4 8
      2          2 4 8
      1        1 2 4 8
    

    This means that, for example, the Fenwick entry A[4] will be responsible for indices 1,2,3,4 and A[4] will contain the total frequency F[1]+F[2]+F[3]+F[4].

    Segment Tree

    In contrast, the responsibilities in a segment tree will look like:

    Index   Responsibilities
      8        1 3 7 15   
      7        1 3 7 14     
      6        1 3 6 13    
      5        1 3 6 12    
      4        1 2 5 11  
      3        1 2 5 10    
      2        1 2 4 9  
      1        1 2 4 8 
    

    Lazy Update

    So why have we done this?

    The reason is that we now have a separate entry responsible for each subdivided range, and this lets us use lazy update.

    The idea with lazy update is that when you wish to update a range of values you only need to recurse into the segment tree and subdivide until you reach an interval that is totally contained within the range to be updated. Once you reach such an interval you do two things:

    1. update the values for that interval
    2. store information at that node to indicate that the segments underneath still need to be updated

    Note that during the recursion you also need to push down up any lazy operations you encounter.

    For example code, try searching for "segment tree" and "lazy propagation".

    Complexity

    Segment trees with lazy propagation will cost O(log(N)) for both queries and updates of any range of values.

提交回复
热议问题