Вычисление специального факториала по модулю p за O(p log N)

156 прочитали
 Статья подготовлена для студентов курса «Алгоритмы для разработчиков» в образовательном проекте OTUS.
Статья подготовлена для студентов курса «Алгоритмы для разработчиков» в образовательном проекте OTUS.

Рассмотрим задачу вычисления формул, состоящих из дробей, где в числителе и в знаменателе присутствуют факториалы (например, биномиальные коэффициенты).

Будем вычислять факториалы по некоторому небольшому простому модулю p, пропуская сами множители p, потому что в дробях множители p сократятся, и результат будет взят по модулю p.

 Статья подготовлена для студентов курса «Алгоритмы для разработчиков» в образовательном проекте OTUS.-2

Видно, что формула делится на несколько блоков одинаковой длины, за исключением последней части:

 Статья подготовлена для студентов курса «Алгоритмы для разработчиков» в образовательном проекте OTUS.-3

Одинаковые блоки содержат общую часть (p - 1)! mod p, что по теореме Вильсона равно p - 1. Чтобы перемножить эти общие части, p - 1 нужно возвести в степень по модулю p (как рассказывается в нашей статье «Быстрое возведение в степень»), однако результат всегда будет 1 или p - 1 в зависимости от чётности показателя.

Значение последнего блока можно вычислить отдельно за O(p). Рассмотрим последние элементы блоков:

 Статья подготовлена для студентов курса «Алгоритмы для разработчиков» в образовательном проекте OTUS.-4

Задача свелась к задаче меньшей размерности (осталось n / p блоков).

 Статья подготовлена для студентов курса «Алгоритмы для разработчиков» в образовательном проекте OTUS.-5

Программа:

 Статья подготовлена для студентов курса «Алгоритмы для разработчиков» в образовательном проекте OTUS.-6

Есть вопросы? Напишите в комментариях!

Знакомьтесь с программой курса «Алгоритмы для разработчиков» и проходите вступительное тестирование!
ПРОЙТИ ТЕСТИРОВАНИЕ