9606. Деление
по модулю
Заданы
три натуральных числа a, b и n.
Вычислите a / b mod n. То есть найдите такое значение x что b * x = a mod n.
Вход. Три натуральных числа a, b,
n (n ≤ 2 * 109, 1 ≤ a, b < n). Известно, что n простое.
Выход. Выведите значение a / b
mod n.
Пример
входа 1 |
Пример
выхода 1 |
3 4 7 |
6 |
|
|
Пример
входа 2 |
Пример
выхода 2 |
4 8 13 |
7 |
возведение
в степень
Поскольку число n простое, то по малой теореме Ферма
выполняется равенство bn-1 mod n = 1 для любого b (1 ≤ b < n). Это равенство можно переписать в
виде (b * bn-2) mod n = 1, откуда следует, что обратным
числом к b является y = bn-2 mod n. Следовательно a / b mod n = a * b-1 mod n = a * y mod n.
Обратное число
можно найти, используя расширенный
алгоритм Евклида. Для этого следует решить сравнение: ax = 1 (mod n). Рассмотрим диофантово
уравнение
ax + ny = 1
и найдем его
частичное решение (x0, y0) с помощью
расширенного алгоритма Евклида. Взяв уравнение ax0 + ny0 = 1 по модулю n, получим ax0 = 1 (mod n). В случае
отрицательного значения x0 к нему следует
прибавить n. Таким образом x0 = a-1 (mod n) является числом,
обратным к a.
Пример
Рассмотрим
второй пример. Вычислим 4 / 8 mod 13. Для этого следует решить уравнение 8 * x = 4 mod 13, откуда
x = (4 * 8-1) mod 13.
Поскольку число
13 простое, то по малой теореме Ферма следует, что 812 mod 13 = 1
или (8 * 811) mod 13 = 1.
Следовательно, 8-1 mod 13 = 811 mod 13 = 5.
Вычисляем ответ:
x = (4 * 8-1) mod 13 = (4
* 5) mod 13 = 20
mod 13 = 7.
Реализация алгоритма
Функция powmod вычисляет значение xn mod m.
long long powmod(long long x, long long n, long long m)
{
if (n == 0) return 1;
if (n % 2 == 0) return powmod((x * x) % m, n / 2, m);
return (x * powmod(x, n - 1, m)) % m;
}
Основная
часть программы. Читаем входные данные.
scanf("%lld %lld %lld", &a, &b, &n);
Вычисляем y = bn-2 mod n, x = a * y mod n.
y = powmod(b, n - 2, n);
x = (a * y) % n;
Выводим
ответ.
printf("%lld\n", x);
Реализация алгоритма – расширенный алгоритм Евклида
#include <stdio.h>
long long a, b, n, d, x,
y, inv, res;
void gcdext(long long a, long long b,
long long &d, long long &x, long long &y)
{
if (b == 0)
{
d = a; x = 1; y = 0;
return;
}
gcdext(b, a % b, d, x, y);
long long s = y;
y = x - (a / b) * y;
x = s;
}
int main(void)
{
scanf("%lld %lld %lld", &a, &b, &n);
// b * inv + n * y = 1
gcdext(b, n, d, inv, y);
if (inv < 0) inv += n;
res = (a * inv) % n;
printf("%lld\n", res);
return 0;
}
Python реализация
Основная
часть программы. Читаем входные данные.
a,
b, n = map(int, input().split())
Вычисляем y = bn-2 mod n, x = a * y mod n.
y = pow(b, n - 2, n)
x =
(a * y) % n
Выводим
ответ.
print(x)