Я нашёл эти статьи, в них уже это описано:
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
должно стать стандартом на раундах CodeForces.why all these downvotes?
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.
How to find inverse modulo when
B mod M = 0
. If you can also add this into your blog, it would be very helpful.There would be no inverse in the same way that multiplying by 0 has no inverse.
There is a way. Instead of just the remainder of
B
you need to store a pair of numbers(p, r)
, wherep
is the maximal integer number such thatB
is divisible byM
to the power ofp
; andr
is the remainder ofB / M^p
moduloM
. We must storeA
the same way.Now if you need to divide
A
byB
and you are sure thatA
is divisible byB
, you can do the following.If
A
is stored as(p_A, r_A)
andB
is stored as(p_B, r_B)
then you subtractp_B
fromp_A
and multiplyr_A
by the modular inverse ofr_B
.I've never used it, but I think it should work.
Do you plan to upload YouTube video on certain topics? (Like number theory, probability or combinatorics?)
Yes
\(^▽^)/