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);

}