Saturday, September 15, 2012

SPOJ RPAR : Raining Parabolas


6906. Raining Parabolas


Problem Summery

Given an array of n items hi ( 0≤i<n ), we have to perform an update operation for a given range [i,j] such that, hx = (hx + f(x))%M, ( i≤x≤j and f(x) = ax2+bx+c ). We also have to perform a query operation for a range [i,j] such that, result = (hi + hi+1 + hi+2 + … + hj)%M.


Solution Idea

Solution idea with the help of a segment tree is quite simple. First, we need to observe the types of information we need to store on each node of the tree. As we will be facing range updates, lazy propagation can be utilized, so, we can have three carry variables, namely ca, cb, cc. If we look closely to the update procedure, parts with x2 are added together and parts with x are added together and there is another part which are the constants. We can resemble them namely with variables, a, b, c, i.e. a is the variable that holds the sum for x2 part, b is the variable that holds the sum for x part and c is the last one that holds the constant part. Also, we can keep the pre-computed values of sum of x2 and x on tree node ranges for the ease of calculation.

Now, let’s dissect the update part. Say, on node p (i to j) we already have in a:
a1xi2 + a2xi+12 + a3xi+22 + … + anxj2
Now we want to add a new parabola (a, b, c) on this range, as only x2 parts will be added here, so the new value of a on this node will be:
(a1+a)xi2 + (a2+a)xi+12 + (a3+a)xi+22 + … + (an+a)xj2
So, we can easily see the extra value added with the previous in variable a:
a * (sum of x2 in range [i,j])

Similarly, for x part, i.e. variable b we can show the added value is:
b * (sum of x in range [i,j])
And for the constant part, i.e. variable c we can show the added value is:
c * n where n is the size of range [i,j];

So we can perform these updates now using lazy propagation, and query is also done in the similar way, the final result for a range is simply the sum of variable a, b, c from that range. And obviously modulus operations must be handled properly.

Have fun!

7 comments:

  1. great blog. Vai, is it possible to write a tutorial blog about this problem http://www.lightoj.com/volume_showproblem.php?problem=1411

    if you have solved it ?

    ReplyDelete
  2. Hasan,https://github.com/zobayer1/SPOJ/blob/master/HORRIBLE.cpp ,
    can you explain your solution,and your lazy propagation implementation?

    ReplyDelete
    Replies
    1. This post should be a sufficient explanation, if it is not, then I would recommend solving some easier ones like GSS1, GSS3 etc.

      Delete
    2. Zobayer,thanks for your reply.I have solved GSS1,GSS3 with segment trees without using lazy propagation.I am not able to implement lazy propagation in segment trees properly.Can you help me with that?
      And how do you decide to use BIT or Segment tree in a particular question?

      Delete
    3. I am not that good with either, if I can reduce the problem to cumulative sum or differences, I would go for BIT, otherwise I will always try to use segment tree. In most of the contests, if a BIT solution passes, judges always accept the segment tree solutions as well.
      And for the lazy propagation, I am not sure whether this reply would be sufficient, this is what happens in short.
      Say you need to add V for each element in range [X, Y], which is a combination of several nodes in a segment tree, then instead of adding V actually over the range, we just keep a variable on each node to signify that, if we go downward from that node, we need to first add the amount, then perform current operation. This is simple, right? This idea is called lazy propagation. Say, you added 5 to a range 101 to 1342. And you have a query for a range 534 to 745. So, during the update phase, we didn't actually add 5 to the ranges actually, we stored that in the largest possible nodes that comprises the range, and during the query, we only fix the values of the nodes we actually need. If you compare these with a code that you have in your hand, I think you will easily see what is happening.

      Delete
    4. you can also try MULTQ3, that one also needs lazy propagation.

      Delete
  3. Thanks for the reply ,Zobayer.I solved MULTQ3.I was trying out RPAR.Can you explain in more detail how you would apply lazy propagation for this problem in particular?
    I tried out the approach which you used in horrible,but it is not working .

    ReplyDelete