Editorial for DMOPC '20 Contest 3 P5 - Tower of Power
Submitting an official solution before solving the problem yourself is a bannable offence.
Author:
Subtask 1
Since  is at most 3, and 
 is prime, we can just directly use Euler's Theorem along with a standard modpow. That is, given a tower 
, we can first compute 
, and then compute 
. The important thing here is that all exponentiations are done with a modulus, since otherwise, even for small values of 
, the numbers rapidly blow up in size. As 
 is prime, we can easily compute 
, and the modular exponentiations are each 
 time (where 
 is the exponent, and bounded by 
). In Python, this approach might look something like the following:
n, m = map(int, input().split())
a1, a2, a3 = map(int, input().split())
print(pow(a1, pow(a2, a3, m - 1), m))
Of course, an actual solution needs to account for both , 
, and the case where 
 (Python will happily evaluate 
, although here it should be 
 – one of the last test cases for subtask 1 covered this, and a few people got tripped up by it).
Time complexity:  (but only works for 
)
Subtask 2
The initial naive approach here is to use the same process as from subtask 1, but simply pass the modulus up the tower by repeatedly taking , and then evaluating from the top down. This approach requires a more general method for computing 
, as the modulus is no longer guaranteed to be prime, and certainly 
 can never be prime, but it also doesn't work because of the requirements we need to use Euler's Theorem: we need the base and the modulus to be coprime. In subtask 1, as the modulus is prime, the only time this isn't the case is when the base is a multiple of the modulus, and the result is trivially 0. However, now we have to deal with the more general case where 
 and 
 share some, not necessarily all, prime factors.
Computing  can be done simply by factorizing 
, which can be done easily in 
 time, and computing 
, and repeatedly applying 
 makes the modulus shrink relatively quickly (it isn't hard to see that after 
 iterations, the result will be 1), so this isn't an issue (Also note that as we apply 
, the cost of factorizing goes down substantially, so this bound is not tight).
The intended solution to the non-coprime case was to use Chinese Remainder Theorem, splitting up  into prime powers. More formally, let 
, where 
 are primes that also divide 
, and 
 is whatever is left over of 
 after dividing out these prime powers. Then, we compute 
, 
, 
, etc., and then "reassemble" the results using CRT:
Computing the first of these is easy, as  is by definition now coprime to 
, so we just continue with the regular approach. For the others, we claim they are usually 
, and when they aren't, they can be directly evaluated. Consider just one prime 
 that divides both 
 and 
, and let 
, and 
 be the highest power of 
 that divides 
. Also, allow 
 to represent the value of the "rest" of the tower (not modulo anything), which we can't necessarily compute directly. Then, we have:
Clearly, if , this whole term is just 0, as the result will be a multiple of 
. If it isn't, we must compute directly, but then this result is manageable, as 
, which is at most 30. Thus, we can just check the next 4 terms of the tower (
), and see whether the result will be at least 
 or not, which gives us 
 time for computing the results from the prime powers.
The actual process of CRT itself is quite fast, basically only relying on the extended Euclidean algorithm, which is  time (depending on how many distinct primes we have in common between the base and the modulus, we might have to do this a few times, but the constant here is small: at most 9 for bounds of 
). Naively, this gives us a total runtime of 
, but we can use the fact that we observed earlier, which is that applying 
 decreases the modulus very rapidly, and we can limit the 
 we need to consider to 
.
Time complexity: 
However, as it turns out, there's a much cleaner solution to write, which doesn't require CRT (and is slightly faster). In the cleaner version, you just ignore the non-coprime issue, but instead when you propagate the modulus up the tower with , you don't reduce it all the way modulo 
. If the exponent is 
, when 
, we leave it alone, but if 
, we reduce it such that we have 
, 
. This abuses the following result:
This result can be proved with the Chinese Remainder Theorem: consider splitting  out into prime powers. By CRT, if the statement is true modulo all the prime powers of 
, it's true modulo 
. Modulo any prime power coprime to 
, Euler's Theorem tells us it's true. Modulo any prime power not coprime to 
, they must be congruent to 0, since 
 is at least the largest exponent of any prime power that divides 
. Writing this more generally,
As long as we don't remove that last  from the exponent, we're fine. One way to look at this is we get to move the Chinese Remainder Theorem from the computations into a proof of an intermediary result, at the cost of our exponents being 
 larger (which costs very little as modular exponentiation is cheap).
Time complexity: 
Comments