Да, есть более быстрый метод: модульное возведение в степень. http://en.wikipedia.org/wiki/Modular_exponentiation
Повторяющееся умножение (ваш алгоритм) выполняется в экспоненциальном времени, а модульное возведение в степень выполняется в полиномиальное время. Вот как это работает:
Допустим, вы хотите, чтобы вычислить А^по модулю М. Во-первых, писать B в двоичной системе:
B = bn,bn-1,...,b1,b0
Это означает, что
B = bn * 2^n + bn-1 * 2^(n-1) + ... + b1 * 2 + b0
Подставляя в выражении A^B:
A^B = A^(2^n)^bn * A^(2^(n-1))^bn-1 * ... * A^2^b1 * A^b0
А^(2^п) могут быть вычислены рекурсивно:
A^(2^n) = (A^(2^(n-1)))^2
Теперь, хитрость заключается в том, чтобы использовать этот идентификатор для вычисления A^(2^я) для каждого я с использованием повторена квадратурой по модулю М. обычных тождеств умножения и возведение в степени удержания для модульной арифметики тоже, так что это является совершенно законным. Полный алгоритм:
input: A,B,M
output: A^B mod M
result = 1
while(B != 0){
if(B is odd){
result = result * A mod M
}
B = B/2
A = A * A mod M
}
return result
C или C++, пожалуйста, сделать свой ум – deW1
Почему вы заботитесь о том, как быстро ваш код работает при условии, что это не правильно? Как это поможет вам быстрее получить неправильный ответ? –
_ «Он работает для 10 из 20 задач» _ Это должно быть первое, что нужно в списке задач. если он работает для задач 20/20, а затем беспокоиться о скорости ... –