Блог пользователя rembocoder

Автор rembocoder, история, 4 года назад, перевод, По-русски

Я нашёл эти статьи, в них уже это описано:

https://codeforces.me/blog/entry/72527

https://codeforces.me/blog/entry/46620

Они обе очень хорошие. но я хотел написать более сжатый пост конкретно про обратный остаток, потому что он требуется во многих задачах, даже не связанных с теорией чисел.

Задача

Есть два целых числа A и B. Предположим, вы знаете, что A делится на B. Но они очень большие, поэтому вы знаете только их остатки по модулю некоторого простого числа M: A % M and B % M. Вы хотели бы узнать остаток их частного – (A / B) % M. Но (A % M) может не делиться на(B % M). Что делать?

Такой вопрос нередок в комбинаторных задачах, например, при подсчёте биномиальных коэффициентов, когда нужно поделить n! на k! и (n - k)!.

Решение

Короткий ответ – вам нужно вычислить B в степени M - 2 по модулю M (с помощью бинарного возведения в степень). Получившееся число называется обратным остатком B. Теперь вы можете умножить A на него, чтобы по сути разделить его на B.

Примечание: это работает только если B % M – не 0, а M – простое.

Реализация

Если вы не используете #define int int64_t
Если вы используете #define int int64_t

Доказательство

Это известная формула, опирающаяся на малую теорему Ферма и на тот факт, что каждый ненулевой элемент кольца остатков по простому модулю имеет ровно один обратный элемент по умножению. Если вы хотите узнать больше, вы можете прочитать упомянутые мною статьи.

  • Проголосовать: нравится
  • +40
  • Проголосовать: не нравится

»
4 года назад, скрыть # |
 
Проголосовать: нравится +18 Проголосовать: не нравится

Перепиши пожалуйста код без #define int int64_t. Человек может скопировать часть кода и облажаться

»
4 года назад, скрыть # |
 
Проголосовать: нравится +10 Проголосовать: не нравится

why all these downvotes?