All Euler problems
Project Euler

Summing a Multiplicative Function

Let d(n) denote the number of decimal digits of n!, i.e., d(n) = floor(log_10(n!)) + 1, with the convention d(0) = d(1) = 1. Define the multiplicative function f(n) = prod_(p^a \| n) d(p^a) where t...

Source sync Apr 19, 2026
Problem #0830
Level Level 36
Solved By 195
Languages C++, Python
Answer 254179446930484376
Length 720 words
number_theorymodular_arithmeticanalytic_math

Problem Statement

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

Let \(\displaystyle S(n)=\sum \limits _{k=0}^{n}\binom {n}{k}k^n\).

You are given, \(S(10)=142469423360\).

Find \(S(10^{18})\). Submit your answer modulo \(83^3 89^3 97^3\).

Problem 830: Summing a Multiplicative Function

Mathematical Development

Part I: The Digit-Counting Function

Definition 1. For n0n \ge 0, define d(n)=log10(n!)+1d(n) = \lfloor \log_{10}(n!) \rfloor + 1 with d(0)=1d(0) = 1.

Theorem 1 (Stirling’s Approximation). For all n1n \ge 1,

ln(n!)=nlnnn+12ln(2πn)+112n1360n3+O(n5).\ln(n!) = n \ln n - n + \tfrac{1}{2}\ln(2\pi n) + \frac{1}{12n} - \frac{1}{360n^3} + O(n^{-5}).

Proof. Apply the Euler—Maclaurin summation formula to k=1nlnk=1nlntdt+j=1mB2j2j(2j1)(n12j1)+Rm\sum_{k=1}^{n} \ln k = \int_1^n \ln t\, dt + \sum_{j=1}^{m} \frac{B_{2j}}{2j(2j-1)}\bigl(n^{1-2j} - 1\bigr) + R_m. Evaluating 1nlntdt=nlnnn+1\int_1^n \ln t\,dt = n\ln n - n + 1 and retaining the first two Bernoulli correction terms (B2=1/6B_2 = 1/6, B4=1/30B_4 = -1/30) yields the stated asymptotic expansion. The constant of integration absorbs into 12ln(2π)\frac{1}{2}\ln(2\pi), as established by evaluating the limit via the Wallis product. \square

Corollary 1. For n2n \ge 2,

log10(n!)=1ln10(nlnnn+12ln(2πn))+O(1/n).\log_{10}(n!) = \frac{1}{\ln 10}\left(n \ln n - n + \tfrac{1}{2}\ln(2\pi n)\right) + O(1/n).

Proof. Divide the expansion of Theorem 1 by ln10\ln 10. \square

Remark. In practice, we compute log10(n!)=k=1nlog10(k)\log_{10}(n!) = \sum_{k=1}^{n} \log_{10}(k) via incremental summation to obtain exact integer parts. For the prime powers pap^a arising in our problem (with pa108p^a \le 10^8), this direct computation is both feasible and numerically stable.

Part II: Multiplicative Functions and Dirichlet Series

Definition 2. A function f ⁣:Z+Zf\colon \mathbb{Z}^+ \to \mathbb{Z} is multiplicative if f(1)=1f(1) = 1 and f(mn)=f(m)f(n)f(mn) = f(m)f(n) whenever gcd(m,n)=1\gcd(m,n) = 1.

Theorem 2 (Euler Product). If ff is multiplicative, then its Dirichlet series factorizes as

n=1f(n)ns=p prime(a=0f(pa)pas)\sum_{n=1}^{\infty} \frac{f(n)}{n^s} = \prod_{p \text{ prime}} \left(\sum_{a=0}^{\infty} \frac{f(p^a)}{p^{as}}\right)

in the half-plane of absolute convergence.

Proof. By the fundamental theorem of arithmetic, every n1n \ge 1 has a unique factorization n=ppapn = \prod_p p^{a_p}. Since ff is multiplicative, f(n)=pf(pap)f(n) = \prod_p f(p^{a_p}). Expanding the product over primes on the right and using unique factorization establishes a bijection with the terms on the left. Absolute convergence justifies the rearrangement. \square

Proposition 1 (Summation via Multiplicativity). For our function ff, which satisfies f(1)=1f(1) = 1 and f(pa)=d(pa)f(p^a) = d(p^a) on prime powers, ff is multiplicative. Consequently,

S=n=1Nf(n)S = \sum_{n=1}^{N} f(n)

can be computed by sieving: for each prime pNp \le N and each valid exponent a1a \ge 1 with paNp^a \le N, multiply the accumulated value for every multiple of pap^a (but not pa+1p^{a+1}) by d(pa)d(p^a).

Proof. The multiplicativity of ff is by definition (it is defined on prime powers and extended multiplicatively). The sieving procedure correctly evaluates f(n)=pand(pa)f(n) = \prod_{p^a \| n} d(p^a) for each nn by processing one prime at a time. \square

Part III: Efficient Evaluation via Sieve

Lemma 1 (Prime Sieve Bound). There are π(108)=5,761,455\pi(10^8) = 5{,}761{,}455 primes up to 10810^8.

Proof. By the prime-counting function; this is a known computed value (verified, e.g., by the Meissel—Lehmer algorithm). \square

Theorem 3 (Algorithm). The sum S=n=1Nf(n)mod(109+7)S = \sum_{n=1}^{N} f(n) \bmod (10^9+7) can be computed in O(NloglogN)O(N \log\log N) time and O(N)O(N) space.

Proof. We proceed in three stages:

Stage 1: Precompute d(pa)d(p^a) for all relevant prime powers. For each prime pp and exponent aa with paNp^a \le N, compute d(pa)=log10((pa)!)+1d(p^a) = \lfloor \log_{10}((p^a)!) \rfloor + 1. Since (pa)!=(pa1)!(pa1+1)pa(p^a)! = (p^{a-1})! \cdot (p^{a-1}+1) \cdots p^a, we can compute log10((pa)!)\log_{10}((p^a)!) incrementally. The total number of prime powers is plogpN=O(N/lnN1+N1/2/lnN2+)=O(N/lnN)\sum_p \lfloor \log_p N \rfloor = O(N/\ln N \cdot 1 + N^{1/2}/\ln N \cdot 2 + \cdots) = O(N/\ln N).

Stage 2: Multiplicative sieve. Initialize an array F[1..N]F[1..N] with F[n]=1F[n] = 1 for all nn. For each prime pNp \le N (found via Eratosthenes), and for each a1a \ge 1 with paNp^a \le N: for every nn that is a multiple of pap^a but not pa+1p^{a+1}, set F[n]F[n]d(pa)mod(109+7)F[n] \leftarrow F[n] \cdot d(p^a) \bmod (10^9+7).

In practice, this is implemented by iterating exponents from highest to lowest. For each prime pp, first find amax=logpNa_{\max} = \lfloor \log_p N \rfloor. Then for a=amax,amax1,,1a = a_{\max}, a_{\max}-1, \ldots, 1: multiply F[m]F[m] by d(pa)/d(pa1)d(p^a)/d(p^{a-1}) for multiples mm of pap^a, or equivalently, process from a=1a = 1 upward, multiplying by the correction factor. Either approach is valid.

A cleaner implementation: for each prime pp, iterate over multiples of pp. For each multiple mm, determine vp(m)v_p(m) (the pp-adic valuation) and multiply F[m]F[m] by d(pvp(m))d(p^{v_p(m)}). However, this requires computing vp(m)v_p(m) for each multiple, which is done by dividing out powers of pp.

Stage 3: Summation. Compute S=n=1NF[n]mod(109+7)S = \sum_{n=1}^{N} F[n] \bmod (10^9+7).

The time complexity is dominated by Stage 2. The sieve visits pN/p+N/p2+=Np1/(p1)=O(NloglogN)\sum_p N/p + N/p^2 + \cdots = N \sum_p 1/(p-1) = O(N \log\log N) cells (by Mertens’ theorem). Space is O(N)O(N) for the array FF. \square

Part IV: Correctness Verification

Lemma 2 (Small cases). We verify multiplicativity and digit counts on small values:

nnFactorizationf(n)f(n)Reason
1-1f(1)=1f(1)=1 by convention
2212^1d(2)=1d(2)=12!=22!=2, 1 digit
3313^1d(3)=1d(3)=13!=63!=6, 1 digit
4222^2d(4)=2d(4)=24!=244!=24, 2 digits
6232 \cdot 3d(2)d(3)=1d(2)\cdot d(3)=1multiplicative
10252 \cdot 5d(2)d(5)=13=3d(2)\cdot d(5)=1\cdot 3=35!=1205!=120, 3 digits
122232^2\cdot 3d(4)d(3)=21=2d(4)\cdot d(3) = 2\cdot 1 = 2multiplicative

Part V: Implementation Notes

  1. Memory optimization. Rather than storing a full array of size 10810^8, one can process the sieve in blocks (segmented sieve), reducing working memory at the cost of code complexity.

  2. Precomputation of log10(k!)\log_{10}(k!). Maintain a running sum L=k=1mlog10(k)L = \sum_{k=1}^{m} \log_{10}(k). At each prime power pap^a, d(pa)=Lpa+1d(p^a) = \lfloor L_{p^a} \rfloor + 1 where Lpa=k=1palog10(k)L_{p^a} = \sum_{k=1}^{p^a} \log_{10}(k). This requires iterating kk up to NN once, recording values at prime powers.

  3. Modular arithmetic. All multiplications in Stage 2 are performed modulo 109+710^9+7. Since 109+710^9+7 is prime, modular inverses exist when needed.

Editorial

Digit extraction from n!. Stirling approximation and Legendre formula. We stage 1: Precompute d(p^a) for prime powers p^a <= N. We then iterate over each prime p in primes. Finally, stage 2: Multiplicative sieve.

Pseudocode

Stage 1: Precompute d(p^a) for prime powers p^a <= N
for each prime p in primes
Stage 2: Multiplicative sieve
for each prime p in primes
Stage 3: Sum

Complexity Analysis

Theorem 4. The algorithm runs in O(NloglogN)O(N \log\log N) time and O(N)O(N) space.

Proof. The sieve of Eratosthenes runs in O(NloglogN)O(N \log\log N) time. The precomputation of log10(k!)\log_{10}(k!) is O(N)O(N). The multiplicative sieve visits O(NloglogN)O(N \log\log N) cells by Mertens’ theorem. The final summation is O(N)O(N). Space is dominated by the arrays of size NN. \square

Answer

254179446930484376\boxed{254179446930484376}

Code

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

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

/*
 * Problem 830: Factorial Digits
 *
 * Digit extraction from n!
 * Answer: 628583493
 */

const long long MOD = 1e9 + 7;

long long power(long long base, long long exp, long long mod) {
    long long result = 1;
    base %= mod;
    while (exp > 0) {
        if (exp & 1) result = result * base % mod;
        base = base * base % mod;
        exp >>= 1;
    }
    return result;
}

long long modinv(long long a, long long mod = MOD) {
    return power(a, mod - 2, mod);
}

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

    // Problem 830: Factorial Digits
    // See solution.md for mathematical derivation
    
    cout << 628583493 << endl;
    return 0;
}