374. Большой модуль
По
заданным b, p, m вычислить значение выражения bp
mod m.
Вход. Содержит несколько тестов. Числа b, p,
m находятся в
отдельных строках. Известно, что 0 £ b, p £ 2147483647, 1 £ m £ 46340.
Выход. Для каждого теста вывести в
отдельной строке значение bp mod m.
Пример входа |
Пример выхода |
3 18132 17
17 1765 3
2374859 3029382
36123 |
13 2
13195 |
рекуррентное соотношение
Из
ограничений на входные данные следует, что в процессе вычисления достаточно
использовать тип данных int. Возведение в степень bp будем
производить с логарифмической временной сложностью O(log p) используя
алгоритм, базирующийся на двоичном разложении показателя степени p:
bp =
Для вычисления значения из первого
теста 318132 (mod 17) следует представить показатель степени в
двоичной системе исчисления: 1813210 = 1000110110101002.
Далее 318132 (mod 17) = 316384 * 31024 * 3512
* 3128 * 364 * 316 * 34 (mod 17) = 13.
Для второго теста 171765
(mod 3) = (17 mod 3) 1765 (mod 3) = 2 1765 (mod 3) = 2.
Функция
pow вычисляет выражение bp mod m с оценкой сложности
O(log p).
int pow(int
b, int p, int
m)
{
int res = 1;
while(p > 0)
{
if (p & 1) res = (res * b) % m;
p >>= 1;
b = (b * b) % m;
}
return res;
}
Прочитав входные значения b, p
и m, следует воспользоваться формулой
bp mod m
= (b mod m)p mod m
При передаче параметров функции pow
основание степени b должно быть не больше чем модуль m. Если
этого не сделать, получим Time Limit. Отдельно следует обработать случай, когда
p = 0: b0 mod m = 1.
while (scanf("%d
%d %d", &b, &p, &m) == 3)
{
b = b % m;
if (!p) res = 1; else
res = pow(b,p,m);
printf("%d\n",res);
}