Editorial for WC '15 Contest 3 J3 - Red Sun Simulator
Submitting an official solution before solving the problem yourself is a bannable offence.
In this problem, we would like to compute two values: the maximum and minimum number of minutes that Superman can be weakened for by the red sun simulator. These two values are always fixed, and knowing them will make the problem trivial to solve. The observation is that if he can be weakened for both the min and max number of minutes, then he can also be weakened by any number of minutes between them. Assuming we know this range, then for every query , we output Y
if and only if is between the min and max number of minutes, inclusive.
We can initialize the min and max to , and then iterate over the minutes while updating them appropriately. Namely, in each minute , one of three possible situations can be true:
- Superman must be weakened (the min and max will each increase by )
- Superman may or may not be weakened (only the max will increase by )
- Superman cannot be weakened (nothing is changed)
Since there are up to intervals to consider for each minute, we must decide how to determine whether the weakening of Superman is mandatory (case 1) or possible (case 2).
For Superman's weakening to be mandatory, either the solar frequency of minute is equal to (and so every value of every interval is a multiple), or every interval for minute solely consists of a single integer which is a multiple of the solar frequency (convince yourself that it is impossible for two consecutive integers to both be a multiple of another integer greater than ). In this case, if even a single interval does not have and as a multiple of , then we know that there is a chance for the RSS to fail at weakening Superman during minute . Whether Superman's weakening is mandatory can be checked using the AND operation on an initially true boolean value as the intervals are being inputted (with no added time complexity).
The harder part is checking whether it's at least possible to weaken Superman during that minute. This is directly doable in linear time with respect to the total length of all intervals in minute . Start with a variable "possible" set to true. Then for each interval , we can check for multiples of with the following for-loop in time.
for (int x = F; x <= B; x += F)
if (A <= x && x <= B)
possible = true;
However, since and may be up to billion, this method will clearly not run in time. We can try mitigating this slowness with tricks like looping starting from , or even generating the multiples of to see if each falls between and like the following:
for (int x = A; x <= B; x++)
if (F % x == 0)
possible = true;
But ultimately, it will still be futile since for values like on intervals , we still have to loop million times. The insight required to overcome this bottleneck is ultimately this: Suppose we want to get the smallest multiple of greater than . If we take and multiply it by again, then we are guaranteed to get a value that is no greater than (since ) and a multiple of (since we just multiplied it by ). Simply adding to the result, we will get the first multiple of greater than . Then, we can just check if this is less than or equal to . This is sufficient to solve the problem (since we know how to determine whether a multiple is in any interval in constant time), but if we want something more compact, then we can play around with the idea to finally deduce that each interval contains at least one multiple of if and only if .
Case 3 occurs when neither case 1 nor case 2 is true, so we can simply do nothing after we determined so. Since every interval and question can be processed in constant time, the above algorithm will have a running time complexity of .
Comments