0 added
0 removed
Original
2026-01-01
Modified
2026-03-10
1
<p>Теги: алгоритмы для разработчиков, вычисление факториала, теорема вильсона, формулы, быстрое возведение в степень, глубина рекурсии</p>
1
<p>Теги: алгоритмы для разработчиков, вычисление факториала, теорема вильсона, формулы, быстрое возведение в степень, глубина рекурсии</p>
2
<p>Рассмотрим задачу вычисления формул, состоящих из дробей, где в числителе и в знаменателе присутствуют факториалы (например,<a>биномиальные коэффициенты</a>).</p>
2
<p>Рассмотрим задачу вычисления формул, состоящих из дробей, где в числителе и в знаменателе присутствуют факториалы (например,<a>биномиальные коэффициенты</a>).</p>
3
<p>Будем вычислять факториалы по некоторому небольшому простому модулю<em>p</em>, пропуская сами множители<em>p</em>, потому что в дробях множители<em>p</em>сократятся, и результат будет взят по модулю<em>p</em>.</p>
3
<p>Будем вычислять факториалы по некоторому небольшому простому модулю<em>p</em>, пропуская сами множители<em>p</em>, потому что в дробях множители<em>p</em>сократятся, и результат будет взят по модулю<em>p</em>.</p>
4
<p>Видно, что формула делится на несколько блоков одинаковой длины, за исключением последней части:</p>
4
<p>Видно, что формула делится на несколько блоков одинаковой длины, за исключением последней части:</p>
5
<p>Одинаковые блоки содержат общую часть (p - 1)! mod p, что по<a>теореме Вильсона</a>равно p - 1. Чтобы перемножить эти общие части, p - 1 нужно возвести в степень по модулю p (как рассказывается в нашей статье "<a>Быстрое возведение в степень</a>"), однако результат всегда будет 1 или p - 1 в зависимости от чётности показателя.</p>
5
<p>Одинаковые блоки содержат общую часть (p - 1)! mod p, что по<a>теореме Вильсона</a>равно p - 1. Чтобы перемножить эти общие части, p - 1 нужно возвести в степень по модулю p (как рассказывается в нашей статье "<a>Быстрое возведение в степень</a>"), однако результат всегда будет 1 или p - 1 в зависимости от чётности показателя.</p>
6
<p>Значение последнего блока можно вычислить отдельно за O(p). Рассмотрим последние элементы блоков:</p>
6
<p>Значение последнего блока можно вычислить отдельно за O(p). Рассмотрим последние элементы блоков:</p>
7
<p>Задача свелась к задаче меньшей размерности (осталось n / p блоков).<strong>Программа</strong>:</p>
7
<p>Задача свелась к задаче меньшей размерности (осталось n / p блоков).<strong>Программа</strong>:</p>
8
def factmod(n, p): res = 1 while n > 1: res = (res * (p - 1 if int(n / p) % 2 else 1)) % p for i in range(2, n % p + 1): res = (res * i) % p n = int(n / p) return res % p<p><em>Есть вопросы? Напишите в комментариях!</em></p>
8
def factmod(n, p): res = 1 while n > 1: res = (res * (p - 1 if int(n / p) % 2 else 1)) % p for i in range(2, n % p + 1): res = (res * i) % p n = int(n / p) return res % p<p><em>Есть вопросы? Напишите в комментариях!</em></p>
9
9