Editorial for Baltic OI '13 P4 - Brunhilda's Birthday
Submitting an official solution before solving the problem yourself is a bannable offence.
Let denote the number of calls Wotan needs to end the game when children are left and let be the set of primes Wotan can choose from.
Dynamic Programming Solution
For points it is enough to evaluate the obvious formula
using dynamic programming. Then all queries can be answered by simple lookup. To handle the case suffices to check whether
(since if is not divisible by after calling less children will be over, but if is at least the product of all numbers Wotan can call, after any call at least children will remain) or to simply set for before evaluating the above formula. Runtime is in both cases.
Greedy Approach
Let us denote the predecessor, i.e. the number of children that are left after Wotan made a perfect call, of as ). If there are multiple solutions, let be the minimum of these numbers. The main point of the solution is the following
Proposition 1. Wotan can call the numbers greedily, i.e. . This fact is—once stated—quite obvious, but it can be established rigorously using the following
Lemma 2. and are both monotonically increasing in .
Proof. We show this for any interval by induction on . Without loss of generality let us assume that . The case is trivial. Otherwise we have as stated above and thus . Since for any , we have . Thus
because of the monotonicity of in .
To show that this suffices for subtask we need to establish an upper bound for . For simplicity let denote .
Lemma 3. Let and . Then .
Proof. We use induction on . Again there is nothing to show for . For we have by assumption and thus
by monotonicity of . Using the monotonicity of we get thus .
Once again using monotonicity we get
Corollary 4. If , then . Especially we have .
Using the prime number theorem stating that the prime is asymptotically as big as one can decrease this bound further to , however, this is not required directly for the solution.
Since we can calculate primitively in we can answer one query in time. This suffices for subtasks and .
DP Over Inverse Function
Let denote the inverse function of , i.e.
Since and thus , we have
Thus having calculated for one can calculate using binary search in the interval . It further suffices to check for given in this interval whether (instead of really calculating , which would be too slow). So one can calculate this function for every needed value of in time (here the additional log-factor mentioned before comes in handy).
With this function one can answer any query in logarithmic time using binary search or simply fill an array of all values in time and then answer queries in . Both suffices to get full score.
Model Solution: Fast Evaluation of the Predecessor Function
Instead of minimizing we can simply maximize the term we subtract (since is fixed), let's call it . If we plot some of those functions for variable and some the image consists of a set of straight lines of slope and "breaks".
Thus for we get the same simple characteristic. If we plot all those functions — both and — and scan through this image from right to left the optimal can only change when a break occurs. Thus if we evaluate at all those breaks of all the -functions we can simply fill in the rest of them by subtracting one from the next one at the right.
For any breakpoint , we have that is for some . Thus to initialize our array of values of it suffices to set for any and increasing . This needs
steps (messing with analytic number theory one can reduce this bound further to but with really good constant factor.
Afterwards one can calculate on the fly in constant time and thus use the simple DP approach from the beginning to get full score.
An implementation using a priority queue to evaluate using the same ideas above is expected to get something around full score, too, depending on the data structure used.
Comments