GPMX2019 Fecha1 Solutions
GPMX2019 Fecha1 Solutions
Primera Fecha
Contest Solutions
This document contains expected solutions for the 10 problems used during the Contest
session.
v1.7
Gran Premio de México 2019 – Primera Fecha 1
First lets get the sum of all differences not considering the restriction of not adding differences if
they are −1, 0 or 1.
Looking the formula presented in the problem statement: the kid with list number i will sum each
of the following numbers ai+1 − ai , ai+2 − ai , ..., aN − ai .
It can be seen that the number the i-th kid has selected will be positive for the first i − 1 kids and
negative in the N −i sums he does, so he contributes a total of (i−1)∗ai −(N −i)∗ai = (i−1−N +i)ai =
(2 ∗ i − N − 1)ai .
Then we can get the sum of all differences without the restriction calculating the sum:
N
P
(2 ∗ i − N − 1)ai
i=1
Now, considering that we don’t want to sum differences with values −1, 0 or 1 lets observe that:
ai − aj = 1 when aj = ai − 1
ai − aj = −1 then aj = ai + 1
For each ocurrence of the value ai − 1 before ai we have added 1 to sum, in the same way for each
ocurrence of the value ai + 1 we have added −1 to the sum. Then if we know how many times the
values ai + 1 and ai − 1 appear before ai in the list we can remove from the total sum the values we are
restricted to use in the sum. So our answer is :
N
P
(2 ∗ i − N − 1)ai + times(ai + 1, i) − times(ai − 1, i)
i=1
In the formula the function times(i,j) counts the ocurrences of the value i in the list before index j.
One way to implement times(i,j) is to traverse for all indexes between 1 and j − 1 and count the
number of indexes k where ak = i. This approach has a O(N 2 ) complexity as we will need to traverse
all the indexes for each value of i, wich is slow to get the solution accepted.
In order to improve the computation of times(i,j) we can see that the values the kids can choose
are relatively small (between 1 and 106 ) then we can keep track of the times each value i has appeared
before index j (times(i,j)) using an array as a table to count the ocurrences increasing the count for
each value each time we see it, this approach takes O(1) to update the array and O(1) to query a value.
The complexity of the algorithm is O(N) and will run in time to be accepted.
Gran Premio de México 2019 – Primera Fecha 2
Let’s first solve the problem considering that the supervisor nor his boss will come any day to the
new branch. In this case Jaime has K boxes and N days to bring all boxes to the new branch, this
problem is the same as summing K with N terms, and is a problem that is solved with separator.
Lets suppose K = 7 and N = 3 We can add N − 1 to choose the number of boxes Jaime delivers on
each day for example.
Then the problem in this case is to count in how many different ways we can select N − 1 elements
(K+N −1)!
from a set of K + N − 1 elements and the answer is (K!)(N −1)!
We know that each day the supervisor comes, Jaime needs to bring at least one box. Let’s suppose
the supervisor comes only one day, then, we know Jaime needs to bring one box that day, but he can
bring the K − 1 boxes left in any way he wants in the N , so the problem is the same as the one described
above but with the K − 1 boxes. The same case applies when the boss comes, Jaime needs to bring
two boxes that day and we need to count the number of ways Jaime can put the K − 2 boxes in the N
days. The days both the boss and the supervisor comes is the same as when only the boss comes as he
already satisfies the contraint given by the supervisor.
Suppose K 0 = K − S − 2 ∗ B + T where K is the initial number of boxes, S the number of days
the supervisor will come, B the number of days the boss will come, and T the number of days both the
(K 0 +N −1)!
suppervisor and the boss comes. Then there are (K 0 !)(N −1)!
To implement this solution is required to consider modular arithmetic in order to deal with the
division and the modulus calculation.
Gran Premio de México 2019 – Primera Fecha 3
This is a graph problem. It is easy to see that vertices in the graph are the cities and roads are the
edges.
The task can be expressed in the following way: Given two graphs using the same set of vertices
S G2 = (V, E2 ) What is the minimum cost of selecting a set Ex ⊆ E2 such that the
V , G1 = (V, E1 ) and
graph Gx = (V, E1 Ex ) is connected (i.e it has only one connected component). The cost is the sum
of costs building each road in Ex .
To find a solution, we first build the Graph G1 from the input. If the graph is connected then the
set Ex is empty and the answer is : “Thank you, Goodbye”.
If G1 is not connected then it has more than one connected components. The minimal cost for Ex
can be determined finding the minimum spanning tree that joins each of the connected components of
G1 as if they were a vertex.
After running kruskal algorithm there are two cases:
• The resulting graph contains more than one connected components, in which case no solution
exists and the answer is : “You better hire someone else”.
• The resulting graph contains only one connected component, in which case the ouput is the sum
of costs of the edges selected by Kruskal algorithm.
Gran Premio de México 2019 – Primera Fecha 4
First observation is to note that since all stations are connected with exactly V − 1 edges then the
rally is a tree.
A trivial solution is to traverse the path for each team and concatenate the codes of the vertices
visited in the path that exists between Es and Ef in the order they appear. If we concatenate the code
Cx to another code C we get the code C ∗ 10d(Cx ) + Cx Where d(C) is the number of digits in C. Doing
this for each queried team will not run in time, the function to concatenate a code can be implemented
then in O(1) so we need O(V) per query and will have a total running time of O(EV) wich is slow for
the problem time limit.
We can divide the path from Es to Ef in two paths, one that goes from Es to LCA(Es , Ef ) and
one that goes from LCA(Es , Ef ) to Ef , where LCA(Es , Ef ) is the lowest common ancestor for stations
Es and Ef . Lets say Code(u, v) is the concatenation of all codes in the path from station u to station
v, then, we can see Code(Es , Ef ) can be obtained considering three paths in the tree:
1. The path from Es to the root r of the tree.
2. The path from the LCA(Es , Ef ) to the root r of the tree.
3. The path from the LCA(Es , Ef ) to the station Ef .
If we remove the code from the second path to the code of the first path and concatenate the code
of the third path we obtain Code(Es , Ef ). To remove the second path from the first path notice that:
Where H(Es , LCA(Es , Ef )) is the last visited station before reaching LCA(Es , Ef ) in the path from
Es to LCA(Es , Ef ), then
Code(Es ,r)−Code(LCA(Es ,Ef ),r)
Code(Es , H(Es , LCA(Es , Ef ))) =
10d(Code(LCA(Es ,Ef ),r))
Notice that the code of the third path is Code(LCA(Es , Ef ), Ef ) to obtain this code we can remove
Code(r, P (LCA(Es , Ef ), Ef )) to Code(r, Ef ) similar as we did before:
Notice that the only variable we don’t know here is d(Code(LCA(Es , Ef ))) but it can be seen that
when we remove a code Cs from the code C we also remove d(Cs ) digits from it, then d(Code(LCA(Es , Ef ))) =
d(Code(r, Ef )) − d(Code(r, P (LCA(Es , Ef ))))
Finally as stated before concatenating Code(LCA(Es , Ef ), Ef ) to Code(Es , H(Es , LCA(Es , Ef )))
will give us Code(Es , Ef ), then:
Note that in order to properly implement this solution it is required to perform all calculations
using modular arithmetic as the codes can grow very fast, to do this, notice that there are a division
involved so it will be required to multiply using the modular multiplicative inverse with respect to the
given modulo instead of dividing.
Gran Premio de México 2019 – Primera Fecha 5
The first observation to make is that a number is odd if its last binary digit is 1. We are then
interested in counting the number of substrings that the last character is ’1’. Also, as there shouldn’t be
leading ’0’s (we know this from the statement : all what scientists know is that the data never started
with an “eye”) the string should start with ’1’ as well.
Based on the previous observation we can see that for any pair of positions (i, j) if Si = Sj = 1
then the substring of S that starts in position i and finishes at j is the binary representation of an odd
number. We need to count such pairs.
A way to do this is to keep two counters one for i and one for j for all values of i found in the range
[0, |S|) if Si == 1 then traverse j in the range [i, |S|) and check if Sj == 1 then we found a pair and
our result increases by 1. Time complexity of this approach is O(N 2 ) where N is —S— and it is slow
to be accepted in the given time limit.
A more efficient approach is to count how many 1s appear in S, let this number be K. Our answer
then is the number of ways you can take a pair from a set of K elements allowing repetitions as the
substring from Si to Si is an odd number. The solution is then : (K)∗(K+1)
2 This approach takes O(N),
which is enough to run in time .
Gran Premio de México 2019 – Primera Fecha 6
Consider the simplified problem in which we only need to determine match results, and do not need to
tell the earliest day in which this result could have been predicted. For each of player x ∈ {1, . . . , N },
we implicitly maintain three sets:
• ABOVE(x): the set of players which are known to win against player x;
• SAME(x): the set of players which are known to draw against player x; and
• BELOW(x): the set of players which are known to lose against player x.
These sets may be efficiently maintained using a disjoint-set union (DSU) data structure. At the
beginning of the tournament, before any matches take place, SAME(x) = {x} and ABOVE(x) = BELOW(x) =
∅. Whenever we learn that player x draws with player y, the following operations need to be performed:
• Merge ABOVE(x) and ABOVE(y).
• Merge SAME(x) and SAME(y).
• Merge BELOW(x) and BELOW(y).
Similarly, whenever we learn that player x wins against player y, the following operations need to
be performed:
• Merge SAME(x) and ABOVE(y).
• Merge BELOW(x) and SAME(y).
• Merge ABOVE(x) and BELOW(y).
Finally, whenever we learn that player x loses to player y, the following operations need to be
performed:
• Merge SAME(x) and BELOW(y).
• Merge BELOW(x) and ABOVE(y).
• Merge ABOVE(x) and SAME(y).
Solving queries for the result of a match between players x and y may be done by consecutively
checking whether SAME(x) = ABOVE(y) (win for player x), SAME(x) = SAME(y) (draw) and SAME(x) =
BELOW(y) (win for player y). If neither of these comparisons is true, the result cannot be determined.
This solves the simplified problem.
For the original problem, we also need to determine the earliest day in which match results could have
been established. The solution is to use a partially persistent DSU, which allows us to query past versions
of the data structure rather than only the latest one. For example, using a partially persistent DSU
with union-by-rank/union-by-size (path compression is not feasible), we may solve queries FIND(x, y, t)
of the form ”did elements x and y belong to the same set after t merges were performed?” in O(log n)
time. A binary search allows us to solve queries FIND-TIME(x, y) of the form ”when were elements x
and y first merged to the same set?” in O(log2 n) time. This in turn allows us to determine the first
moment when player x was known to win/draw/lose against player y.
The key idea is to store the time when each merge operation took place. For implementation details,
please refer to https://pastebin.com/CtiaZ7MB, which contains a solution running in O(M log N +
Q log2 N ) time. This is enough to get Accepted.
Alternatively, the operation FIND-TIME(x, y) may be implemented in O(log n) time by skipping the
binary search. This brings the running time down to O((M + Q) log N ).
Gran Premio de México 2019 – Primera Fecha 7
We look for all the possible ways of representing X as the sum of consecutive numbers.
So we are looking for the different values of d such that d + (d + 1) + (d + 2) + · · · + (d + k − 1) = X
Where k is the number of days Baker will travel.
Notice that in order to exist a way for X to be represented as the sum of at least two consecutive
numbers then X is a trapezoidal number. So the problem can be stated as: in how many ways can X
be represented as a trapezoidal number? This value is known as the politeness of a number. For every
x, the politeness of x equals the number of odd divisors of x that are greater than one. One way to see
this is that if x has an odd divisor y. Then y consecutive integers centered on x/y have x as their sum.
If a representation has an odd number of terms, x/y is the middle term, while if it has an even
number of terms and its minimum value is m it may be extended in a unique way to a longer sequence
with the same sum and an odd number of terms, by including the 2m−1 numbers −(m−1), −(m−2), ...,
−1, 0, 1, ..., m − 2, m − 1. After this extension, again, x/y is the middle term. By this construction, the
polite representations of a number and its odd divisors greater than one may be placed into a one-to-one
correspondence, giving a bijective proof of the characterization of polite numbers and politeness.
Solution to the problem is the number of odd divisors of X - 1, since 1 is an odd divisor of X where
d = X and Baker wouldn’t travel for at least two days.
k
αk
The number of divisors of a number X = pα α1 Q
0 ∗ p1 ∗ ... ∗ pk = (αi + 1) In order to count only
0
i=0
odd divisors we need to remove al factors 2 from X factorization which can be done dividing X by 2
until the resulting number is not a divisor of 2 or just omiting the α value for the factors of 2 in the
factorization.
Gran Premio de México 2019 – Primera Fecha 8
The first thing to note is that if we sort the tolerance each problem will take from the partner then we
can simulate if a problem should be taken or not as described in both scenarios.
So, for the first scenario after the set is sorted in decreasing order, we decide to take the first problem
if it’s less than T , if we don’t take it we continue with the next problem, if we take it then T = T − probi
and continue until T = 1 or after we iterated over all problems.
For the second scenario we apply the same as on the first one but with the list sorted in ascending
order.
Time complexity is based on the sorting algorithm, any sorting algorithm that take O(NlogN) will
work in time.
Gran Premio de México 2019 – Primera Fecha 9
The problem can be divided in two subproblems, one to compute all PINs for all the values possible
in the range [1, 105 ], the second problem is to use the computed data as input to answer the queries
problem.
For the first part, let’s observe that any value n that finishes in trailing zeros can be represented as:
n = s ∗ 10q = s ∗ 2q ∗ 5q
Where s is the value before the zeroes and k the number of zeroes n has at the end. If n = K! then
our pin is smod105 .
Observe from above formula, that one way to remove the zeroes from the factorial is to not add
them to the number in the first place. If we know the values of pk and qk , being respectively the number
of times 2 appears as a factor in K! and the number of times 5 appears as a factor in the K!, then
s = 2(pk −qk ) ∗ D(K) (note that in this formula we are only multiplying values and then we can carry
the modulo without problems) where D(K) is the result of multiplying all values between 1 and K not
taking any factor 2 nor factors 5.
To implement this part we can keep track of the values for pk , qk , and D(K) for all values of K and
using fast exponentiation methods compute the PIN values for all possible values of K in O(NlogN).
Once we have this part solved, we can use a succint data structure that properly encodes the data
to answer each query in at most O(logN) per query. Some data structures that can solve this type of
queries efficiently are wavelet trees and persistent segment trees.
Gran Premio de México 2019 – Primera Fecha 10
Now that we know how to sum the perimeters for a given configuration, lets sum all of them, we
know i can take values between 0 and q then we need to sum:
q q q q
2 mpq−i + npi = 2 mpq−i + npi = 2 mpq−i + npi
P P P P
i=0 i=0 i=0 i=0
q
mpq−i :
P
Let’s focus in
i=0
q q q
mpq−i = m pq−i = m pq + pq−1 + pq−2 + · · · + p1 + p0 = m pi
P P P
i=0 i=0 i=0
The problem is reduced to the sum of a geometric series which can be written as
pq+1 −1
2(m + n) p−1
There are two important things to consider in the solution, first, that based on possible values for
the input it is required to use a fast exponentiation method, binary exponentiation can help. The second
one is that we are dividing and obtaining a modulus, it is important to use the multiplicative inverse of
p − 1 with respect to the modulus to multiply instead of divide.