Diophantine Reciprocals II
Find the least value of n such that the number of distinct solutions of (1)/(x) + (1)/(y) = (1)/(n) exceeds four million (4,000,000).
Problem Statement
This archive keeps the full statement, math, and original media on the page.
In the following equation $x$, $y$, and $n$ are positive integers. $$\dfrac{1}{x} + \dfrac{1}{y} = \dfrac{1}{n}$$ It can be verified that when $n = 1260$ there are $113$ distinct solutions and this is the least value of $n$ for which the total number of distinct solutions exceeds one hundred.
What is the least value of $n$ for which the number of distinct solutions exceeds four million?
Note: This problem is a much more difficult version of Problem 108 and as it is well beyond the limitations of a brute force approach it requires a clever implementation.
Problem 110: Diophantine Reciprocals II
Mathematical Foundation
Theorem 1. (Algebraic Transformation — same as Problem 108) The equation with positive integers is equivalent to , and the number of solutions with is .
Proof. See Problem 108, Theorems 1 and 2.
Theorem 2. (Divisor Count of a Square) If , then .
Proof. See Problem 108, Theorem 3.
Theorem 3. (Required Bound) We need , i.e., .
Since is always odd, . The condition gives , so (since is odd).
Proof. is a product of odd numbers , hence odd. For odd , . The inequality gives , and since is odd, .
Theorem 4. (Optimization as a Discrete Minimization Problem) Minimize (equivalently, minimize ) subject to and , where is the -th prime.
Proof. The constraint is necessary for optimality by the same argument as Problem 108 Lemma 1: swapping a larger exponent to a smaller prime strictly decreases while preserving .
Lemma 1. (Search Space Bounds) The number of primes satisfies , and the maximum exponent satisfies but in practice suffices (since , using more primes with exponent 1 is more efficient than increasing one exponent).
Proof. With primes all having exponent , . For , we need . However, some primes may have exponent , so can be smaller. The bound follows from . For the maximum exponent: if and all other exponents are 1, then , and it suffices to have small with large. The practical bound is sufficient.
Theorem 5. (Solution) The minimum is:
with exponent sequence giving:
and .
Proof. The exponent sequence is non-increasing with 12 primes. The divisor product is . Assigning exponents to the first 12 primes in decreasing order: .
To verify minimality: any alternative exponent sequence with yields . This is confirmed by exhaustive search over all feasible non-increasing exponent sequences (bounded by primes and ), computing for each and retaining the minimum.
Editorial
Same approach as Problem 108 but with threshold 8,000,001 for d(n^2). Uses log-space comparison to handle large n values. We first generate the primes required by the search, then enumerate the admissible combinations and retain only the values that satisfy the final test.
Pseudocode
target = 8000001 // need d(n^2) >= 8000001
primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47]
best_n = infinity
search(product=1, n=1, prime_idx=0, max_exp=15)
Return best_n
If product >= target then
best_n = min(best_n, n)
return
If prime_idx >= len(primes) then
return
p = primes[prime_idx]
For a from min(max_exp, ...) down to 1:
new_n = n * p^a
If new_n >= best_n then
continue // prune
new_product = product * (2*a + 1)
search(new_product, new_n, prime_idx + 1, a)
Complexity Analysis
- Time: The recursive search explores non-increasing exponent sequences with aggressive pruning ( and ). The number of feasible sequences is bounded by the number of partitions of into at most 15 parts, weighted by decreasing exponent constraints. In practice, the search visits on the order of nodes and completes in milliseconds.
- Space: for the recursion stack, where .
Answer
Code
Each problem page includes the exact C++ and Python source files from the local archive.
#include <bits/stdc++.h>
using namespace std;
/*
* Problem 110: Diophantine Reciprocals II
*
* Same as Problem 108 but threshold is 4,000,000.
* Need d(n^2) >= 8,000,001.
*
* We use logarithms to avoid overflow when comparing n values,
* since n can be very large. We track log(n) and reconstruct
* the actual n at the end using __int128 or careful multiplication.
*/
const int NPRIMES = 20;
int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71};
double log_primes[NPRIMES];
double best_log_n;
vector<int> best_exponents;
void dfs(int idx, int max_exp, double log_n, long long div_count, vector<int>& exponents) {
if (div_count >= 8000001LL) {
if (log_n < best_log_n) {
best_log_n = log_n;
best_exponents = exponents;
}
return;
}
if (idx >= NPRIMES) return;
if (log_n >= best_log_n) return;
for (int e = 1; e <= max_exp; e++) {
double new_log = log_n + e * log_primes[idx];
if (new_log >= best_log_n) break;
exponents.push_back(e);
dfs(idx + 1, e, new_log, div_count * (2 * e + 1), exponents);
exponents.pop_back();
}
}
int main() {
for (int i = 0; i < NPRIMES; i++)
log_primes[i] = log((double)primes[i]);
best_log_n = 1e18;
vector<int> exponents;
dfs(0, 40, 0.0, 1, exponents);
// Reconstruct the actual n using the best exponents
// Use __int128 or careful computation
// Since answer fits in long long (9350130049860600), we can use long long
long long n = 1;
for (int i = 0; i < (int)best_exponents.size(); i++) {
for (int j = 0; j < best_exponents[i]; j++) {
n *= primes[i];
}
}
cout << n << endl;
return 0;
}
"""
Problem 110: Diophantine Reciprocals II
Find the least n such that the number of distinct solutions of
1/x + 1/y = 1/n exceeds 4,000,000.
Same approach as Problem 108 but with threshold 8,000,001 for d(n^2).
Uses log-space comparison to handle large n values.
"""
import math
PRIMES = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
LOG_PRIMES = [math.log(p) for p in PRIMES]
TARGET = 8_000_001
best_log_n = float('inf')
best_exponents = []
def search(idx, max_exp, log_n, div_count, exponents):
global best_log_n, best_exponents
if div_count >= TARGET:
if log_n < best_log_n:
best_log_n = log_n
best_exponents = exponents[:]
return
if idx >= len(PRIMES):
return
if log_n >= best_log_n:
return
for e in range(1, max_exp + 1):
new_log = log_n + e * LOG_PRIMES[idx]
if new_log >= best_log_n:
break
exponents.append(e)
search(idx + 1, e, new_log, div_count * (2 * e + 1), exponents)
exponents.pop()
search(0, 40, 0.0, 1, [])
# Reconstruct n
n = 1
for i, e in enumerate(best_exponents):
n *= PRIMES[i] ** e
print(n)
# Verification
if __name__ == "__main__":
d_n2 = 1
for e in best_exponents:
d_n2 *= (2 * e + 1)
solutions = (d_n2 + 1) // 2
factors = {PRIMES[i]: best_exponents[i] for i in range(len(best_exponents))}
print(f"n = {n}")
print(f"Factorization: {factors}")
print(f"d(n^2) = {d_n2}")
print(f"Solutions = {solutions}")
print(f"Exceeds 4,000,000: {solutions > 4_000_000}")