Как я уже упоминал в своих комментариях, это действительно не имеет особого отношения к интеллектуальным алгоритмам. Проблема может быть полностью сведена с использованием некоторой теории элементарных чисел. Это даст алгоритм O (1).
В китайской теореме о остатках говорится, что если мы знаем некоторое число x по модулю 2 и по модулю 5, то мы знаем это по модулю 10. Поэтому найти a^b^c по модулю 10 можно свести к нахождению a^b^c по модулю 2 и a^b^c по модулю 5. Маленькая теорема Ферма гласит, что для любого простого p, если p не делит a, то a^(p-1) = 1 (mod p), поэтому a^n = a^(n mod (p-1)) (mod p). Если p делит a, то, очевидно, a^n = 0 (mod p) для любого n> 0. Заметим, что x^n = x (mod 2) для любого n> 0, поэтому a^b^c = a (mod 2).
Остается найти a^b^c mod 5, который сводится к нахождению b^c mod 4. К сожалению, мы не можем использовать ни теорему китайского остатка, ни небольшую теорему Ферма. Тем не менее, mod 4 есть только 4 возможности для b, поэтому мы можем проверить их отдельно. Если мы начнем с b = 0 (mod 4) или b = 1 (mod 4), то, конечно, b^c = b (mod 4).Если мы имеем b = 2 (mod 4), то легко видеть, что b^c = 2 (mod 4), если c = 1 и b^c = 0 (mod 4), если c> 1. Если b = 3 (mod 4), то b^c = 3, если c четно, и b^c = 1, если c нечетно. Это дает нам b^c (mod 4) для любых b и c, которые затем дают нам a^b^c (mod 5), все в постоянное время.
Наконец, с помощью a^b^c = a (mod 2) мы можем использовать китайскую теорему о остатках, чтобы найти a^b^c (mod 10). Для этого требуется сопоставление между (x (mod 2), y (mod 5)) и z (mod 10). Теорема о китайском остатке только говорит нам, что это отображение биективно, оно не говорит нам, как его найти. Однако есть только 10 вариантов, поэтому это легко сделать на листе бумаги или с помощью небольшой программы. Когда мы найдем это отображение, мы просто сохраним его в массиве, и мы можем выполнить весь расчет в O (1).
Кстати, это будет реализация моего алгоритма в питоне:
# this table only needs to be calculated once
# can also be hard-coded
mod2mod5_to_mod10 = [[0 for i in range(5)] for j in range(2)]
for i in range(10):
mod2mod5_to_mod10[i % 2][i % 5] = i
[a,b,c] = [int(input()) for i in range(3)]
if a % 5 == 0:
abcmod5 = 0
else:
if b % 4 == 0 or b % 4 == 1:
bcmod4 = b % 4
elif b == 2:
if c == 1:
bcmod4 = 2
else:
bcmod4 = 0
else:
if c % 2 == 0:
bcmod4 = 1
else:
bcmod4 = 3
abcmod5 = ((a % 5)**bcmod4) % 5
abcmod2 = a % 2
abcmod10 = mod2mod5_to_mod10[abcmod2][abcmod5]
print(abcmod10)
Обратите внимание, что вы должны быть в состоянии уменьшить это полностью, если вы используете малую теорему Ферма и китайскую теорему об остатках. Другими словами, с некоторой математикой вы должны иметь возможность использовать алгоритм O (1). – JSQuareD
Если вы поднимете число 'a' на большие и большие мощности, последняя цифра начнет цикл. Можете ли вы выяснить, как определить, где в цикле вы приземляетесь, не вычисляя все 'b^c'? – user2357112
@scummy точка (я думаю) состоит в том, что 10 = 2 * 5 и 2,5 - простые числа. CRT может позволить вам найти результат mod 10 с учетом результатов mod 2 и mod 5 –