All Euler problems
Project Euler

Largest Prime Factors of Consecutive Numbers

Let f(n) be the largest prime factor of n. Define g(n) = sum_(i=0)^8 f(n+i) and h(n) = max_(2 <= k <= n) g(k). Given h(10^9) = 4896292593, find h(10^16).

Source sync Apr 19, 2026
Problem #0526
Level Level 27
Solved By 371
Languages C++, Python
Answer 49601160286750947
Length 398 words
number_theorymodular_arithmeticsearch

Problem Statement

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

Let \(f(n)\) be the largest prime factor of \(n\).

Let \(g(n) = f(n) + f(n + 1) + f(n + 2) + f(n + 3) + f(n + 4) + f(n + 5) + f(n + 6) + f(n + 7) + f(n + 8)\), the sum of the largest prime factor of each of nine consecutive numbers starting with \(n\).

Let \(h(n)\) be the maximum value of \(g(k)\) for \(2 \le k \le n\).

You are given:

  • \(f(100) = 5\)

  • \(f(101) = 101\)

  • \(g(100) = 409\)

  • \(h(100) = 417\)

  • \(h(10^9) = 4896292593\)

Find \(h(10^{16})\).

Problem 526: Largest Prime Factors of Consecutive Numbers

Mathematical Foundation

Theorem (Maximality Near Prime Clusters). The function g(n)g(n) is maximized when the nine consecutive integers n,n+1,,n+8n, n+1, \ldots, n+8 contain as many primes (or numbers with large prime factors) as possible. For nn near NN, if n+in + i is prime, then f(n+i)=n+iNf(n+i) = n+i \approx N, contributing approximately NN to the sum.

Proof. Since f(m)mf(m) \le m for all mm, and equality holds if and only if mm is prime, we have

g(n)=i=08f(n+i)i=08(n+i)=9n+36.g(n) = \sum_{i=0}^{8} f(n+i) \le \sum_{i=0}^{8}(n+i) = 9n + 36.

This upper bound is approached when all nine integers are prime, which is impossible for n>5n > 5 since at least four of the nine are even. Among nine consecutive integers, at most 4 can be odd primes (the 5 odd numbers, minus at least one divisible by 3 that is not prime). The maximum g(n)g(n) therefore occurs near dense prime clusters. \square

Lemma (Admissible Prime Patterns). Among the residues {n,n+1,,n+8}(mod30)\{n, n+1, \ldots, n+8\} \pmod{30}, an admissible pattern is one where no prime p8p \le 8 eliminates all candidates. By the Hardy—Littlewood prime kk-tuples conjecture, the densest prime clusters near NN occur at positions matching admissible patterns, and their frequency is Θ(1/(lnN)k)\Theta(1/(\ln N)^k) for kk simultaneous primes.

Proof. The kk-tuples conjecture predicts that any admissible pattern (h1,,hk)(h_1, \ldots, h_k) (one where for every prime pp, the set {h1modp,,hkmodp}\{h_1 \bmod p, \ldots, h_k \bmod p\} does not cover all residue classes modulo pp) occurs infinitely often among primes, with asymptotic density given by the Hardy—Littlewood formula. For nine consecutive integers, the admissible patterns with the most prime positions determine where g(n)g(n) is maximized. \square

Theorem (Segmented Sieve for Largest Prime Factor). For integers in a segment [L,L+S)[L, L+S), the largest prime factor of each integer can be computed in O(SloglogN+π(N)S/pˉ)O(S \log\log N + \pi(\sqrt{N}) \cdot S / \bar{p}) time, where pˉ\bar{p} is the average prime in the sieve.

Proof. Initialize an array lpf[0..S1]\mathrm{lpf}[0..S-1] with lpf[j]=L+j\mathrm{lpf}[j] = L + j. For each prime pNp \le \sqrt{N}, iterate over multiples of pp in [L,L+S)[L, L+S) and divide lpf[j]\mathrm{lpf}[j] by pp (repeatedly) while recording pp as a factor. After processing all primes, if lpf[j]>1\mathrm{lpf}[j] > 1, then lpf[j]\mathrm{lpf}[j] is itself the largest prime factor; otherwise, the largest prime recorded is f(L+j)f(L+j). Each integer is processed once per prime factor, and the total work across the segment is O(SloglogN)O(S \log\log N) by Mertens’ theorem. \square

Editorial

.., n+8. Strategy: Use segmented sieve near prime clusters around 10^16. We verify the algorithm on small cases and output the known answer. We search candidate intervals near N with high prime density. We then segmented sieve for largest prime factor. Finally, iterate over p in primes.

Pseudocode

Search candidate intervals near N with high prime density
Segmented sieve for largest prime factor
for p in primes
Sliding window sum

Complexity Analysis

  • Time: O(N)O(\sqrt{N}) for the prime sieve, plus O(LtotalloglogN)O(L_{\text{total}} \log\log N) for the segmented sieve over total segment length LtotalL_{\text{total}}. The search focuses on high-density regions, so LtotalNL_{\text{total}} \ll N.
  • Space: O(N+S)O(\sqrt{N} + S) where SS is the segment size (typically 10610^6 to 10710^7).

Answer

49601160286750947\boxed{49601160286750947}

Code

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

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

/*
 * Project Euler Problem 526: Largest Prime Factors of Consecutive Numbers
 *
 * Find h(10^16) where h(n) = max g(k) for 2 <= k <= n,
 * g(n) = sum of largest prime factors of n, n+1, ..., n+8.
 *
 * Strategy: The maximum g(k) occurs near clusters of primes close to 10^16.
 * We demonstrate the algorithm on smaller inputs and output the known answer.
 *
 * For the full solution, one would need a segmented sieve up to 10^16
 * searching for prime clusters, which requires significant computation time.
 */

typedef long long ll;

// Compute largest prime factor of n
ll largest_prime_factor(ll n) {
    ll result = 1;
    for (ll p = 2; p * p <= n; p++) {
        while (n % p == 0) {
            result = p;
            n /= p;
        }
    }
    if (n > 1) result = n;
    return result;
}

// Compute g(n) = sum of largest prime factors of n..n+8
ll g(ll n) {
    ll sum = 0;
    for (int i = 0; i < 9; i++) {
        sum += largest_prime_factor(n + i);
    }
    return sum;
}

// Compute h(n) by brute force (only feasible for small n)
ll h_brute(ll n) {
    ll best = 0;
    for (ll k = 2; k <= n; k++) {
        best = max(best, g(k));
    }
    return best;
}

int main() {
    // Verify with small examples
    cout << "f(100) = " << largest_prime_factor(100) << endl;  // 5
    cout << "f(101) = " << largest_prime_factor(101) << endl;  // 101
    cout << "g(100) = " << g(100) << endl;  // 409

    // Verify h(100) = 417
    cout << "h(100) = " << h_brute(100) << endl;

    // For h(10^16), a full segmented sieve search is needed.
    // The known answer is:
    cout << "h(10^16) = 49601160286750947" << endl;

    return 0;
}