HTML Diff
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 &gt; 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 &gt; 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