All Euler problems
Project Euler

An Enormous Factorial

For a prime p, define N(p,q) = sum_(n=0)^q T_n * p^n where T_n is generated by S_0 = 290797, S_(n+1) = S_n^2 mod 50515093, T_n = S_n mod p. Let NF(p,q) = v_p(N(p,q)!) (the p -adic valuation of N(p,...

Source sync Apr 19, 2026
Problem #0288
Level Level 10
Solved By 1,987
Languages C++, Python
Answer 605857431263981935
Length 204 words
modular_arithmeticnumber_theorybrute_force

Problem Statement

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

For any prime \(p\) the number \(N(p, q)\) is defined by \(N(p, q) = \sum _{n = 0}^q T_n \cdot p^n\)

with \(T_n\) generated by the following random number generator:

\(S_0 = 290797\)

\(S_{n + 1} = S_n^2 \bmod 50515093\)

\(T_n = S_n \bmod p\)

Let \(\operatorname {Nfac}(p, q)\) be the factorial of \(N(p, q)\).

Let \(\operatorname {NF}(p, q)\) be the number of factors \(p\) in \(\operatorname {Nfac}(p, q)\).

You are given that \(\operatorname {NF}(3,10000) \bmod 3^{20} = 624955285\).

Find \(\operatorname {NF}(61, 10^7) \bmod 61^{10}\).

Problem 288: An Enormous Factorial

Mathematical Foundation

Theorem (Legendre’s Formula). For any prime pp and positive integer nn,

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

where sp(n)s_p(n) is the digit sum of nn in base pp.

Proof. The first equality is Legendre’s classical formula: n/pk\lfloor n/p^k \rfloor counts the multiples of pkp^k in {1,,n}\{1, \ldots, n\}, and each multiple of pkp^k contributes 1 to the exponent for each power p1,p2,,pkp^1, p^2, \ldots, p^k. The second equality follows from writing n=i=0mdipin = \sum_{i=0}^{m} d_i p^i and computing k=1mn/pk=k=1mi=kmdipik=i=1mdipi1p1=nsp(n)p1\sum_{k=1}^{m} \lfloor n/p^k \rfloor = \sum_{k=1}^{m} \sum_{i=k}^{m} d_i p^{i-k} = \sum_{i=1}^{m} d_i \cdot \frac{p^i - 1}{p-1} = \frac{n - s_p(n)}{p-1}. \quad\square

Theorem (Base-pp Structure of N(p,q)N(p,q)). Since 0Tn<p0 \le T_n < p for all nn, the number N(p,q)=n=0qTnpnN(p,q) = \sum_{n=0}^{q} T_n \cdot p^n has base-pp digits exactly (T0,T1,,Tq)(T_0, T_1, \ldots, T_q) (from least to most significant). Consequently,

N(p,q)pk=j=kqTjpjk.\left\lfloor \frac{N(p,q)}{p^k} \right\rfloor = \sum_{j=k}^{q} T_j \cdot p^{j-k}.

Proof. Since each Tn{0,1,,p1}T_n \in \{0, 1, \ldots, p-1\}, the representation Tnpn\sum T_n p^n is already the base-pp expansion (no carries). Division by pkp^k simply shifts the digits. \quad\square

Theorem (Efficient Modular Computation). We have

vp(N!)=j=1qTji=0j1pi=j=1qTjG(j),v_p(N!) = \sum_{j=1}^{q} T_j \cdot \sum_{i=0}^{j-1} p^i = \sum_{j=1}^{q} T_j \cdot G(j),

where G(j)=pj1p1=1+p++pj1G(j) = \frac{p^j - 1}{p - 1} = 1 + p + \cdots + p^{j-1}. Modulo pep^e, this reduces to

vp(N!)modpe=j=1qTjG(min(j,e))modpe.v_p(N!) \bmod p^e = \sum_{j=1}^{q} T_j \cdot G(\min(j, e)) \bmod p^e.

Proof. Substituting the floor formula into Legendre’s formula:

vp(N!)=k=1qj=kqTjpjk=j=1qTjk=1jpjk=j=1qTjG(j).v_p(N!) = \sum_{k=1}^{q} \sum_{j=k}^{q} T_j p^{j-k} = \sum_{j=1}^{q} T_j \sum_{k=1}^{j} p^{j-k} = \sum_{j=1}^{q} T_j \cdot G(j).

For the modular reduction: G(j)=1+p++pj1G(j) = 1 + p + \cdots + p^{j-1}. When jej \ge e, the terms pe,pe+1,p^e, p^{e+1}, \ldots vanish modulo pep^e, so G(j)G(e)(modpe)G(j) \equiv G(e) \pmod{p^e}. Thus TjG(j)TjG(min(j,e))(modpe)T_j \cdot G(j) \equiv T_j \cdot G(\min(j,e)) \pmod{p^e}. \quad\square

Editorial

Key insight: Since T_n are the base-p digits of N(p,q), Legendre’s formula gives: v_p(N!) = sum_{j=1}^{q} T_j * (1 + p + … + p^{j-1}) Mod p^e, the geometric sum caps at e terms. We precompute G(1), G(2), …, G(e). Finally, generate T_n and accumulate.

Pseudocode

Precompute G(1), G(2), ..., G(e)
Generate T_n and accumulate

Complexity Analysis

  • Time: O(q)O(q) where q=107q = 10^7. Each of the q+1q+1 iterations involves O(1)O(1) modular arithmetic.
  • Space: O(e)=O(10)O(e) = O(10) for the precomputed geometric sums.

Answer

605857431263981935\boxed{605857431263981935}

Code

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

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

int main() {
    // Problem: Find NF(61, 10^7) mod 61^10
    // NF(p,q) = v_p(N(p,q)!) where N(p,q) = sum T_n * p^n
    // Using Legendre: v_p(N!) = sum_{j=1}^{q} T_j * (1 + p + p^2 + ... + p^{j-1})
    // Mod p^e, the geometric sum caps at e terms.

    const long long p = 61;
    const int q = 10000000;
    const int e = 10;

    // Compute modulus = p^e
    long long mod = 1;
    for (int i = 0; i < e; i++) mod *= p;
    // mod = 61^10

    // Precompute geometric sums G[k] = 1 + p + p^2 + ... + p^{k-1} mod p^e
    // For k = 1..e
    vector<long long> G(e + 1, 0);
    long long pw = 1;
    for (int k = 1; k <= e; k++) {
        G[k] = (G[k - 1] + pw) % mod;
        if (k < e) pw = pw * p % mod;
    }

    // Generate T_n and accumulate
    long long s = 290797;
    long long result = 0;

    for (int n = 0; n <= q; n++) {
        long long t = s % p;
        if (n >= 1) {
            int idx = (n < e) ? n : e;
            result = (result + t * G[idx]) % mod;
        }
        // Advance RNG
        s = s * s % 50515093LL;
    }

    cout << result << endl;
    return 0;
}