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

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

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

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

https://codeforces.net/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
  • Проголосовать: не нравится

»
21 месяц назад, # |
  Проголосовать: нравится +18 Проголосовать: не нравится

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

  • »
    »
    21 месяц назад, # ^ |
      Проголосовать: нравится -64 Проголосовать: не нравится

    Сделал два варианта.

    Мне кажется, что использование #define int int64_t должно стать стандартом на раундах CodeForces.

»
21 месяц назад, # |
  Проголосовать: нравится +10 Проголосовать: не нравится

why all these downvotes?

  • »
    »
    21 месяц назад, # ^ |
      Проголосовать: нравится +14 Проголосовать: не нравится

    Maybe they didn't like how it was written. I've updated the post to make it clearer.

    My goal was not to write an excessive material, but just provide information that every participant is required to know to solve many of the CF problems.

    • »
      »
      »
      21 месяц назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      How to find inverse modulo when B mod M = 0. If you can also add this into your blog, it would be very helpful.

      • »
        »
        »
        »
        21 месяц назад, # ^ |
          Проголосовать: нравится +8 Проголосовать: не нравится

        There would be no inverse in the same way that multiplying by 0 has no inverse.

      • »
        »
        »
        »
        21 месяц назад, # ^ |
          Проголосовать: нравится 0 Проголосовать: не нравится

        There is a way. Instead of just the remainder of B you need to store a pair of numbers (p, r), where p is the maximal integer number such that B is divisible by M to the power of p; and r is the remainder of B / M^p modulo M. We must store A the same way.

        Now if you need to divide A by B and you are sure that A is divisible by B, you can do the following.

        If A is stored as (p_A, r_A) and B is stored as (p_B, r_B) then you subtract p_B from p_A and multiply r_A by the modular inverse of r_B.

        I've never used it, but I think it should work.

    • »
      »
      »
      21 месяц назад, # ^ |
        Проголосовать: нравится 0 Проголосовать: не нравится

      Do you plan to upload YouTube video on certain topics? (Like number theory, probability or combinatorics?)