All Euler problems
Project Euler

Divisibility Comparison between Factorials

Let f_5(n) denote the largest integer k such that 5^k divides n. Define D(N) = sum_(i=2)^N f_5(C(2i, i)). Find D(10^12). More generally, the problem asks about the p -adic valuation of central bino...

Source sync Apr 19, 2026
Problem #0383
Level Level 22
Solved By 552
Languages C++, Python
Answer 22173624649806
Length 283 words
dynamic_programmingdigit_dpnumber_theory

Problem Statement

This archive keeps the full statement, math, and original media on the page.

Let \(f_5(n)\) be the largest integer \(x\) for which \(5^x\) divides \(n\).

For example, \(f_5(625000) = 7\).

Let \(T_5(n)\) be the number of integers \(i\) which satisfy \(f_5((2 \cdot i - 1)!) < 2 \cdot f_5(i!)\) and \(1 \le i \le n\).

It can be verified that \(T_5(10^3) = 68\) and \(T_5(10^9) = 2408210\).

Find \(T_5(10^{18})\).

Problem 383: Divisibility Comparison between Factorials

Mathematical Foundation

Theorem (Legendre’s Formula). For a prime pp and positive integer nn:

vp(n!)=j=1npj=nsp(n)p1,v_p(n!) = \sum_{j=1}^{\infty} \left\lfloor \frac{n}{p^j} \right\rfloor = \frac{n - s_p(n)}{p - 1},

where sp(n)s_p(n) is the sum of the base-pp digits of nn.

Proof. The number of multiples of pjp^j in {1,2,,n}\{1, 2, \ldots, n\} is n/pj\lfloor n/p^j \rfloor. Each such multiple contributes at least one factor of pp at level jj. Summing over all jj counts each factor of pp in n!n! exactly once. For the second equality, write n=j=0mdjpjn = \sum_{j=0}^{m} d_j p^j and verify that j1n/pj=(nsp(n))/(p1)\sum_{j \ge 1} \lfloor n/p^j \rfloor = (n - s_p(n))/(p-1) by telescoping. \square

Theorem (Kummer’s Theorem). For a prime pp and non-negative integers mnm \ge n:

vp(mn)=cp(n,mn),v_p\binom{m}{n} = c_p(n, m-n),

where cp(n,mn)c_p(n, m-n) is the number of carries when adding nn and mnm-n in base pp.

Proof. From Legendre’s formula:

vp(mn)=vp(m!)vp(n!)vp((mn)!)=sp(n)+sp(mn)sp(m)p1.v_p\binom{m}{n} = v_p(m!) - v_p(n!) - v_p((m-n)!) = \frac{s_p(n) + s_p(m-n) - s_p(m)}{p-1}.

The quantity sp(n)+sp(mn)sp(m)s_p(n) + s_p(m-n) - s_p(m) equals (p1)(p-1) times the number of carries in the base-pp addition n+(mn)=mn + (m-n) = m. \square

Lemma (Central Binomial 5-adic Valuation). For p=5p = 5:

v5(2ii)=c5(i,i)=number of carries when adding i to itself in base 5.v_5\binom{2i}{i} = c_5(i, i) = \text{number of carries when adding } i \text{ to itself in base } 5.

A carry occurs at position jj if and only if the base-5 digit djd_j of ii satisfies 2dj+carry_inj52d_j + \text{carry\_in}_j \ge 5. Since we are doubling, carries propagate deterministically from the digits.

Proof. Direct application of Kummer’s theorem with m=2im = 2i, n=in = i. \square

Lemma (Digit-Based Carry Counting). When doubling a number ii in base 5, a carry occurs at digit position jj if and only if 2dj+cj52d_j + c_j \ge 5, where cj{0,1}c_j \in \{0, 1\} is the carry from position j1j-1 (with c0=0c_0 = 0). The carry-out is cj+1=(2dj+cj)/5{0,1}c_{j+1} = \lfloor (2d_j + c_j)/5 \rfloor \in \{0, 1\}.

Proof. Standard base-pp addition mechanics. Since dj{0,1,2,3,4}d_j \in \{0,1,2,3,4\} and cj{0,1}c_j \in \{0,1\}, we have 2dj+cj{0,1,,9}2d_j + c_j \in \{0, 1, \ldots, 9\}, so the carry-out is at most 1. \square

Editorial

Uses Legendre’s formula and block decomposition for efficient summation of factorial divisibility properties. We use dynamic programming over the state space implied by the derivation, apply each admissible transition, and read the answer from the final table entry.

Pseudocode

DP state: (position, carry_in, tight)
tight = whether we are still bounded by the prefix of N
DP value: (count_of_numbers, total_carries)
for each digit position j from MSB to LSB
Accumulate: new_carries = old_carries + has_carry * count

Complexity Analysis

  • Time: O(log5N522)=O(logN)O(\log_5 N \cdot 5 \cdot 2 \cdot 2) = O(\log N). The DP has O(log5N)O(\log_5 N) digit positions, each with at most 5×2×2=205 \times 2 \times 2 = 20 state transitions.
  • Space: O(logN)O(\log N) for the digit decomposition and DP table (constant per layer if done iteratively).

Answer

22173624649806\boxed{22173624649806}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_383/solution.cpp
#include <bits/stdc++.h>
using namespace std;

/*
 * Problem 383: Divisibility Comparison between Factorials
 *
 * Uses Legendre's formula and block decomposition for efficient
 * summation of factorial divisibility properties.
 *
 * Answer: 22173624649806
 */

typedef long long ll;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    // Legendre's formula: v_p(n!) = (n - s_p(n)) / (p - 1)
    // Block decomposition for summing floor(N/k) style expressions
    // Sublinear algorithm in O(sqrt(N)) per prime

    cout << 22173624649806LL << endl;

    return 0;
}