Опишите алгоритм подсчёта числа завершающих нулей в десятичной записи факториала n! и обобщите результат на произвольную систему счисления с основанием b (включая составные основания); какие тонкости возникают при разложении основания b на простые множители и при больших n, и как реализовать вычисление эффективно?

22 Окт в 14:53
6 +1
0
Ответы
1
Коротко — с формулами и практическими замечаниями.
Идея. Число завершающих нулей в записи n!n!n! в системе с основанием bbb равно наибольшему ttt такого, что btb^tbt делит n!n!n!. Пусть при разложении основания
b=∏p∣bpep b=\prod_{p\mid b} p^{e_p}
b=pb pep
(все простые множители ppp с их степенями epe_pep ). Обозначим vp(n!)v_p(n!)vp (n!) — показатель степени простого ppp в разложении n!n!n!. Тогда
vp(n!)=∑k≥1⌊npk⌋ v_p(n!)=\sum_{k\ge1}\left\lfloor\frac{n}{p^k}\right\rfloor
vp (n!)=k1 pkn
(Лежандрова формула), и число завершающих нулей
Zb(n)=min⁡p∣b⌊vp(n!)ep⌋. Z_b(n)=\min_{p\mid b}\left\lfloor\frac{v_p(n!)}{e_p}\right\rfloor.
Zb (n)=pbmin ep vp (n!) .

Пример (десятичная система b=10=2⋅5b=10=2\cdot5b=10=25): Z10(n)=min⁡(v2(n!),v5(n!))=v5(n!)Z_{10}(n)=\min(v_2(n!),v_5(n!))=v_5(n!)Z10 (n)=min(v2 (n!),v5 (n!))=v5 (n!), поскольку v2(n!)≥v5(n!)v_2(n!)\ge v_5(n!)v2 (n!)v5 (n!). Для n=100n=100n=100: v5(100!)=⌊100/5⌋+⌊100/25⌋=20+4=24v_5(100!)=\lfloor100/5\rfloor+\lfloor100/25\rfloor=20+4=24v5 (100!)=100/5+100/25=20+4=24.
Тонкости и практические замечания
- Разложение bbb на простые множители:
- Если bbb невелик (напр., 64‑бит), достаточно перебора делителей до b\sqrt bb ; сложность примерно O(b)O(\sqrt b)O(b ).
- Для больших bbb используйте быстрые алгоритмы факторизации (например, пробные делители + алгоритм Полларда ρ \rho ρ), иначе невозможно корректно получить все epe_pep .
- Если в разложении окажется простой множитель p>np>np>n, то vp(n!)=0v_p(n!)=0vp (n!)=0 и итог Zb(n)=0Z_b(n)=0Zb (n)=0.
- Вычисление vp(n!)v_p(n!)vp (n!) для большого nnn:
- Сумма по степеням pkp^kpk ограничена тем, что pk≤np^k\le npkn. Число слагаемых =O(log⁡pn)=O(\log_p n)=O(logp n).
- При вычислении аккуратно увеличивать степень powerpowerpower и проверять переполнение: останавливать, когда power>npower>npower>n или при умножениях проверять power>n/ppower>n/ppower>n/p.
- Размеры чисел:
- vp(n!)≤nv_p(n!)\le nvp (n!)n, поэтому для очень больших nnn (больше 64‑бит) используйте типы с произвольной точностью или 128‑бит, если нужно.
- Результат Zb(n)≤nZ_b(n)\le nZb (n)n.
Эффективная реализация (алгоритм)
1. Проверить b≥2b\ge2b2. Если нет — ошибка.
2. Факторизовать bbb: получить набор пар (p,ep)(p,e_p)(p,ep ).
3. Для каждой пары (p,ep)(p,e_p)(p,ep ):
- Вычислить vp(n!)v_p(n!)vp (n!) через
vp(n!)=∑k=1∞⌊npk⌋, v_p(n!)=\sum_{k=1}^{\infty}\left\lfloor\frac{n}{p^k}\right\rfloor,
vp (n!)=k=1 pkn ,
на практике цикл: power=ppower=ppower=p; while power≤npower\le npowern: add ⌊n/power⌋\lfloor n/power\rfloorn/power; multiply powerpowerpower на ppp (осторожно с переполнением).
- Вычислить ⌊vp(n!)/ep⌋\left\lfloor v_p(n!)/e_p\right\rfloorvp (n!)/ep .
4. Вернуть минимум этих значений:
Zb(n)=min⁡(p,ep)⌊vp(n!)ep⌋. Z_b(n)=\min_{(p,e_p)}\left\lfloor\frac{v_p(n!)}{e_p}\right\rfloor.
Zb (n)=(p,ep )min ep vp (n!) .

Сложность: факторизация bbb доминирует; для фиксированного набора простых ppp суммарная стоимость вычисления всех vp(n!)v_p(n!)vp (n!) равна O ⁣(∑p∣blog⁡pn)=O(ω(b)log⁡n)O\!\left(\sum_{p\mid b}\log_p n\right)=O(\omega(b)\log n)O(pb logp n)=O(ω(b)logn), где ω(b)\omega(b)ω(b) — число различных простых делителей bbb.
Дополнительные замечания
- При многократных запросах по разным nnn и одному bbb факторизацию bbb делайте один раз.
- Для очень больших bbb или при требовании гарантированной скорости используйте оптимальные факторизаторы (Поллард ρ \rho ρ, ECM).
- Если требуется не только число нулей, но и фактическое число n!n!n! в системе с основанием bbb — это гораздо сложнее и требует больших целых типов или модульных/вычислительных методов.
Готов помочь с примером кода (на Python/C++), если нужно.
22 Окт в 16:08
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир