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...
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:
The “+1” accounts for the trivial factorization itself. Equivalently:
where the sum over proper divisors includes as the base case (corresponding to “use as a single factor”).
Dirichlet Series
The Dirichlet generating function is:
This follows because in Dirichlet convolution: the DGF satisfies , giving .
Multiplicative Structure
While is not multiplicative, it satisfies useful identities:
- for prime
- (namely and )
- (compositions of )
- for distinct primes (namely , , )
Concrete Values
| Factorizations of | ||
|---|---|---|
| 2 | 1 | |
| 3 | 1 | |
| 4 | 2 | |
| 6 | 3 | |
| 8 | 4 | |
| 12 | 8 factorizations | 8 |
| 16 | 8 | |
| 24 | 16 |
Derivation
Algorithm: Sieve-Like DP
Compute for using a divisor-sieve approach:
- Initialize and for .
- For each from 1 to , for each multiple :
- (this adds the contribution of factorizations starting with factor ).
This runs in time (harmonic sum).
Alternative: Recursive with Memoization
For each , recursively sum over proper divisors of .
Proof of Correctness
Theorem. The sieve computes for all .
Proof. Each proper divisor of contributes to when is processed and its contribution propagated to multiple . Since we iterate over all and all multiples, every divisor pair is covered exactly once.
Corollary. gives the analytic continuation, confirming the asymptotic for a constant determined by the pole structure.
Complexity Analysis
- Sieve DP: time, space.
- Recursive: worst case, where is the divisor count function.
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#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;
}
"""
Problem 627: Counting Products
f(n) = number of ordered factorizations of n into factors >= 2.
F(N) = sum_{n=2}^{N} f(n).
Dirichlet series: sum f(n)/n^s = 1/(2 - zeta(s)).
Recurrence: f(n) = sum_{d|n, d<n} f(d), f(1) = 1.
Method 1: Sieve-like DP in O(N log N)
Method 2: Recursive with memoization (verification)
"""
# --- Method 1: Sieve DP ---
def solve_sieve(N: int) -> list:
"""Compute f(n) for n=1..N using sieve-like DP."""
f = [0] * (N + 1)
f[1] = 1
for d in range(1, N + 1):
for m in range(2 * d, N + 1, d):
f[m] += f[d]
return f
# --- Method 2: Recursive ---
def solve_recursive(N: int) -> list:
"""Compute f(n) recursively."""
f = [0] * (N + 1)
f[1] = 1
for n in range(2, N + 1):
total = 0
d = 1
while d * d <= n:
if n % d == 0:
if d < n:
total += f[d]
if d != n // d and n // d < n:
total += f[n // d]
d += 1
f[n] = total
return f
# Verify
N = 1000
f_sieve = solve_sieve(N)
f_rec = solve_recursive(N)
for n in range(1, N + 1):
assert f_sieve[n] == f_rec[n], f"Mismatch at n={n}"
# Known values
assert f_sieve[1] == 1
assert f_sieve[2] == 1
assert f_sieve[4] == 2
assert f_sieve[6] == 3
assert f_sieve[8] == 4
assert f_sieve[12] == 8
assert f_sieve[16] == 8
# f(p^k) = 2^{k-1}
for k in range(1, 10):
assert f_sieve[2**k] == 2**(k-1), f"f(2^{k}) = {f_sieve[2**k]}, expected {2**(k-1)}"
F_N = sum(f_sieve[2:])
print(f"F({N}) = {F_N}")
print("All verifications passed.")