algorithmdata-structuressegment-treerange-querylazy-propagation

How is it possible to apply the lazy approach to update a segment tree if the update is more complex than simple addition or multiplication?


Consider this question. In this segment tree solution, we are updating all nodes of the tree in the given range. Is it possible to apply lazy propagation to this problem?

Edit: Consider that in every update operation arr[i] = (1-(1-arr[i])*a), where L<=i<=R and a is a constant.


Solution

  • I'll assume your query operation is finding the sum in a range [L, R].

    You certainly want to do this efficiently, probably in O(log n) per operation.

    You need a way to store data in the lazy field that allows you to compute the updates when traversing the tree for a query.

    Let's see if we can write the update in a nicer way:

    v = 1 - (1 - v) * a
      = 1 - (a - av)
      = 1 - a + av
    

    If we do this twice:

    1 - a + av = 1 - (1 - [1 - a + av]) * a
               =  1 - (a - a + a**2 - a**2 v)
               = 1 - a + a - a**2 + a**2 v
               = 1 - a**2 + a**2 v
    

    Which is equivalent to (applied to an entire range):

    1. Multiply by a
    2. Subtract a
    3. Add 1

    When updating the lazy field, it's clear that you just increase the exponent of a.

    You can do all of these 3 lazily as described in the lazy propagation article you link to.

    So your update operation can be split into 3 lazy updates, each done in O(log n) time, for a total time of O(log n).