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