1

Given an array arr which is initialized to 0 i.e. arr[i]=0 where 0 < i < n

two operation are performed on it

  1. update k r x

    Update does the following:

    for(i=k;i<=r;i++)
    {
        arr[i]=x;
        x+=x;
    }
    
  2. query k r

    Query computes the following sum:

    for(i=k;i<=r;i++)
    {
        sum+=arr[i];
    }
    print(sum);
    

My solution:
I thought of brute force but it is slow. I thought of segment tree but in segment tree update is performed by constant amount so it fails. What might be a good algorithm to solve this?

Constrains

size of array is <=10^5

number of operation(update,query) <=10^5

OmG
  • 18,337
  • 10
  • 57
  • 90
nil96
  • 313
  • 1
  • 3
  • 12

1 Answers1

2

What you are looking for is Lazy Propagation in Segment Trees. We create an array lazy[] with size same as that of the segment tree array. The idea is that we can avoid recursive calls in update by postponing them and do those updates only when required.

My code below does the updating and sum extraction for the predefined data, you can fiddle with main to accept user data in your desired pattern and add tweaks like x+=x etc.

https://ideone.com/kZsJ0E

I suggest that you open the code and read the explanation below side by side to understand better, as lazy propagation is often tough to grasp.

How it works:

  • Initially, the all entries in the lazy[] array are set to be 0, meaning that there is no leftover work to be done in the range which that node represents.
  • To update segment tree at array indexes from qs (query start) to qe (query end):

    -> If current segment tree node has any pending update, then we assign that node (lazy_value)*(length of interval it represents) and assign the lazy values for its children as new_value

    -> If current node's range lies completely in update query range.

    i) Update the Current node, by assigning it (lazy_value)*(length of interval it represents)
    
    ii) Postpone updates to children by setting lazy values for children nodes as new_value
    

    -> If current node's range overlaps with update range, follow the same approach as above simple update.

    a. Recur for left and right children.

    b. Update current node using results of left and right calls.

  • Now, when we use the get_sum procedure, there also we'll update the current node if it has any pending updates and postpone updates to children.

Overall, it is difficult to explain the whole working of lazy propagation here, though I hope that the code and the explanation help.

For more on lazy propagation, you can see

https://www.hackerearth.com/notes/segment-tree-and-lazy-propagation/

Avikalp Srivastava
  • 139
  • 1
  • 1
  • 9