Модульное возведение в степень

Как в C / C ++ вычислить (a^b)%m, где b не умещается в 64 бита? Другими словами, есть ли способ вычислить указанное выше значение, используя b%m вместо b?

И есть ли какой-либо алгоритм, который может вычислить вышеуказанный результат за O(log(b)) или O(log(b%m)) время?


person sabari    schedule 12.07.2012    source источник
comment
Это больше похоже на математический вопрос.   -  person Luchian Grigore    schedule 12.07.2012
comment
Попробуйте math.stackexchange.com   -  person Luchian Grigore    schedule 12.07.2012
comment
Вы имеете в виду, где b не помещается в 64 бита? В обычном алгоритме возведения в степень результат накапливается путем умножения на a, если установлен следующий бит b, а затем возведения в квадрат. Это кажется довольно простым для больших b, для больших a и m сложно.   -  person tbroberg    schedule 12.07.2012
comment
Да, и допустим, b - это число Фибоначчи, а a & m ‹10 ^ 9. Как мне найти (a ^ b)% m. Учитывая, что я использую алгоритм возведения в степень матрицы log (n) для нахождения b. Как мне использовать промежуточные значения b?   -  person sabari    schedule 12.07.2012


Ответы (1)


Согласно теореме Эйлера, если a и m взаимно просты:

ab mod m = ab mod phi(m) mod m

поэтому, если b велико, вы можете использовать значение b % phi(m) вместо b. phi(m) - это общая функция Эйлера, которую можно легко вычислить, если вы знаете разложение m на простые множители. .

После того, как вы уменьшили значение b таким образом, используйте возведение в степень возведением в квадрат для вычисления модульного возведение в степень в O(log (b % phi(m))).

person interjay    schedule 12.07.2012
comment
придираться: это верно, только если a и m взаимно просты. - person Henrik; 12.07.2012
comment
@Henrik: Это означает, что он будет работать, даже если m простое и a ‹m. Поправьте меня, если я ошибаюсь. - person sabari; 12.07.2012
comment
@Henrik: Верно, я забыл об этом, спасибо. Сабари: Да, в этом случае это сработает. - person interjay; 12.07.2012
comment
Функция Кармайкла является обобщением Totient для непростых чисел. См. Мой ответ на тот же вопрос здесь stackoverflow.com/questions/11272437/calculating -abmod / - person Viktor Latypov; 12.07.2012
comment
@ViktorLatypov: Я не понимаю, как помогает функция Кармайкла, поскольку она по-прежнему требует, чтобы a и m были взаимно простыми. - person interjay; 13.07.2012