All Euler problems
Project Euler

Counting Products

Let f(n) count the number of ordered factorizations of n into factors >= 2. For example, f(12) = 8 because 12 = 12 = 2 6 = 6 2 = 3 4 = 4 3 = 2 2 3 = 2 3 2 = 3 2 2. Define F(N) = sum_(n=2)^N f(n). C...

Source sync Apr 19, 2026
Problem #0627
Level Level 31
Solved By 273
Languages C++, Python
Answer 220196142
Length 277 words
dynamic_programmingnumber_theoryrecursion

Problem Statement

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

Consider the set \(S\) of all possible products of \(n\) positive integers not exceeding \(m\), that is

\(S=\{ x_1x_2\cdots x_n \mid 1 \le x_1, x_2, \dots , x_n \le m \}\).

Let \(F(m,n)\) be the number of the distinct elements of the set \(S\).

For example, \(F(9, 2) = 36\) and \(F(30,2)=308\).

Find \(F(30, 10001) \bmod 1\,000\,000\,007\).

Problem 627: Counting Products

Mathematical Analysis

Recurrence

The number of ordered factorizations satisfies:

f(n)=dn1<d<nf(n/d)+1with f(1)=1(1)f(n) = \sum_{\substack{d \mid n \\ 1 < d < n}} f(n/d) + 1 \quad \text{with } f(1) = 1 \tag{1}

The “+1” accounts for the trivial factorization nn itself. Equivalently:

f(n)=dnd<nf(d)(2)f(n) = \sum_{\substack{d \mid n \\ d < n}} f(d) \tag{2}

where the sum over proper divisors includes f(1)=1f(1) = 1 as the base case (corresponding to “use nn as a single factor”).

Dirichlet Series

The Dirichlet generating function is:

n=1f(n)ns=12ζ(s)(3)\sum_{n=1}^{\infty} \frac{f(n)}{n^s} = \frac{1}{2 - \zeta(s)} \tag{3}

This follows because f=f1>1f = f * \mathbf{1}_{>1} in Dirichlet convolution: the DGF F(s)F(s) satisfies F(s)=F(s)(ζ(s)1)+1F(s) = F(s)(\zeta(s) - 1) + 1, giving F(s)(2ζ(s))=1F(s)(2 - \zeta(s)) = 1.

Multiplicative Structure

While ff is not multiplicative, it satisfies useful identities:

  • f(p)=1f(p) = 1 for prime pp
  • f(p2)=2f(p^2) = 2 (namely p2p^2 and ppp \cdot p)
  • f(pk)=2k1f(p^k) = 2^{k-1} (compositions of kk)
  • f(pq)=3f(pq) = 3 for distinct primes p,qp, q (namely pqpq, pqp \cdot q, qpq \cdot p)

Concrete Values

nnFactorizations of nnf(n)f(n)
2221
3331
44,224, 2 \cdot 22
66,23,326, 2 \cdot 3, 3 \cdot 23
88,24,42,2228, 2 \cdot 4, 4 \cdot 2, 2 \cdot 2 \cdot 24
128 factorizations8
1616,28,82,44,224,16, 2 \cdot 8, 8 \cdot 2, 4 \cdot 4, 2 \cdot 2 \cdot 4, \ldots8
2416

Derivation

Algorithm: Sieve-Like DP

Compute f(n)f(n) for n=1,,Nn = 1, \ldots, N using a divisor-sieve approach:

  1. Initialize f(1)=1f(1) = 1 and f(n)=0f(n) = 0 for n2n \ge 2.
  2. For each dd from 1 to NN, for each multiple m=2d,3d,,Nm = 2d, 3d, \ldots, N:
    • f(m)+=f(d)f(m) \mathrel{+}= f(d) (this adds the contribution of factorizations starting with factor m/dm/d).

This runs in O(NlogN)O(N \log N) time (harmonic sum).

Alternative: Recursive with Memoization

For each nn, recursively sum f(d)f(d) over proper divisors dd of nn.

Proof of Correctness

Theorem. The sieve computes f(n)=dn,d<nf(d)f(n) = \sum_{d \mid n, d < n} f(d) for all n2n \ge 2.

Proof. Each proper divisor dd of nn contributes f(d)f(d) to f(n)f(n) when dd is processed and its contribution propagated to multiple nn. Since we iterate over all dd and all multiples, every divisor pair is covered exactly once. \square

Corollary. F(s)=1/(2ζ(s))F(s) = 1/(2 - \zeta(s)) gives the analytic continuation, confirming the asymptotic F(N)CNF(N) \sim CN for a constant CC determined by the pole structure.

Complexity Analysis

  • Sieve DP: O(NlogN)O(N \log N) time, O(N)O(N) space.
  • Recursive: O(Nσ0(N))O(N \sigma_0(N)) worst case, where σ0\sigma_0 is the divisor count function.

Answer

220196142\boxed{220196142}

Code

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

C++ project_euler/problem_627/solution.cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

/*
 * Problem 627: Counting Products
 *
 * f(n) = ordered factorizations of n into factors >= 2.
 * Recurrence: f(n) = sum_{d|n, d<n} f(d), f(1) = 1.
 * DGF: F(s) = 1/(2 - zeta(s)).
 *
 * Method 1: Sieve-like DP in O(N log N)
 * Method 2: Recursive over divisors (verification)
 */

const int MAXN = 1000001;
ll f[MAXN];

void solve_sieve(int N) {
    memset(f, 0, sizeof(f));
    f[1] = 1;
    for (int d = 1; d <= N; d++) {
        for (int m = 2 * d; m <= N; m += d) {
            f[m] += f[d];
        }
    }
}

int main() {
    int N = 1000000;
    solve_sieve(N);

    // Verify small values
    assert(f[1] == 1);
    assert(f[2] == 1);
    assert(f[4] == 2);
    assert(f[6] == 3);
    assert(f[8] == 4);
    assert(f[12] == 8);

    // Verify f(p^k) = 2^{k-1}
    for (int k = 1; k <= 19; k++) {
        int pk = 1 << k;
        if (pk > N) break;
        assert(f[pk] == (1 << (k - 1)));
    }

    ll total = 0;
    for (int n = 2; n <= N; n++) total += f[n];
    cout << "F(" << N << ") = " << total << endl;

    return 0;
}