All Euler problems
Project Euler

Prime Triples and Geometric Sequences

Let S(n) be the sum of a + b + c over all triples (a, b, c) of prime numbers with a < b < c < n such that a + 1, b + 1, c + 1 form a geometric sequence. Given S(100) = 1035, find S(10^8).

Source sync Apr 19, 2026
Problem #0518
Level Level 11
Solved By 1,867
Languages C++, Python
Answer 100315739184392
Length 249 words
number_theorymodular_arithmeticsequence

Problem Statement

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

Let $S(n) = \displaystyle \sum a + b + c$ over all triples $(a, b, c)$ such that:

  • $a$, $b$ and $c$ are prime numbers.

  • $a < b < c < n$.

  • $a+1$, $b+1$, and $c+1$ form a geometric sequence.

For example, $S(100) = 1035$ with the following triples: $(2, 5, 11)$, $(2, 11, 47)$, $(5, 11, 23)$, $(5, 17, 53)$, $(7, 11, 17)$, $(7, 23, 71)$, $(11, 23, 47)$, $(17, 23, 31)$, $(17, 41, 97)$, $(31, 47, 71)$, $(71, 83, 97)$.

Find $S(10^8)$.

Problem 518: Prime Triples and Geometric Sequences

Mathematical Foundation

Theorem 1 (Geometric Sequence Characterization). Three positive integers A<B<CA < B < C form a geometric sequence if and only if B2=ACB^2 = AC.

Proof. If the common ratio is r>1r > 1, then B=ArB = Ar and C=Ar2C = Ar^2, so B2=A2r2=AAr2=ACB^2 = A^2 r^2 = A \cdot Ar^2 = AC. Conversely, if B2=ACB^2 = AC with A<B<CA < B < C, set r=B/A>1r = B/A > 1; then C=B2/A=Ar2C = B^2/A = Ar^2. \square

Theorem 2 (Parametrization). Let a,b,ca, b, c be primes with a<b<ca < b < c and (a+1,b+1,c+1)(a+1, b+1, c+1) in geometric progression. Then there exist positive integers k,x,yk, x, y with x>y1x > y \geq 1 and gcd(x,y)=1\gcd(x, y) = 1 such that

a+1=ky2,b+1=kxy,c+1=kx2.a + 1 = ky^2, \quad b + 1 = kxy, \quad c + 1 = kx^2.

Proof. From (b+1)2=(a+1)(c+1)(b+1)^2 = (a+1)(c+1), write the common ratio as r=(b+1)/(a+1)=x/yr = (b+1)/(a+1) = x/y in lowest terms (gcd(x,y)=1\gcd(x,y) = 1, x>y1x > y \geq 1). Then a+1a + 1 must be divisible by y2y^2: set k=(a+1)/y2k = (a+1)/y^2. We get b+1=(a+1)x/y=kxyb + 1 = (a+1) \cdot x/y = kxy and c+1=(a+1)x2/y2=kx2c + 1 = (a+1) \cdot x^2/y^2 = kx^2. Both are positive integers since gcd(x,y)=1\gcd(x,y) = 1. \square

Lemma 1 (Integrality Constraint). For b+1=kxyb + 1 = kxy and c+1=kx2c + 1 = kx^2 to be integers, it suffices that gcd(x,y)=1\gcd(x, y) = 1 (which is given by the reduced-fraction representation).

Proof. Since k,x,yk, x, y are positive integers and a+1=ky2a + 1 = ky^2, the expressions kxykxy and kx2kx^2 are manifestly integers. \square

Lemma 2 (Bound on Parameters). For c+1=kx2<n+1c + 1 = kx^2 < n + 1 (i.e., c<nc < n), we need kx2nkx^2 \leq n. Thus xnx \leq \sqrt{n} and kn/x2k \leq n / x^2.

Proof. From c=kx21<nc = kx^2 - 1 < n, we get kx2nkx^2 \leq n. Since k1k \geq 1, xnx \leq \sqrt{n}. For fixed xx, kn/x2k \leq n/x^2. \square

Editorial

We sieve primes up to n. Finally, enumerate triples. 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

Sieve primes up to n
Enumerate triples

Complexity Analysis

  • Time: The sieve takes O(nloglogn)O(n \log\log n). The main loop iterates over xx up to n104\sqrt{n} \approx 10^4, for each xx over yy up to x1x - 1, and for each (x,y)(x, y) over kk up to n/x2n/x^2. The total number of (x,y,k)(x, y, k) triples is x=2ny<xn/x2xn/xO(nlogn)=O(nlogn)\sum_{x=2}^{\sqrt{n}} \sum_{y < x} n/x^2 \approx \sum_x n/x \approx O(n \log\sqrt{n}) = O(n \log n), but the gcd\gcd filter and primality checks reduce the constant. In practice, runtime is dominated by the sieve at O(n)O(n).
  • Space: O(n)O(n) for the prime sieve (can use a bitarray for n=108n = 10^8).

Answer

100315739184392\boxed{100315739184392}

Code

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

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

const int LIMIT = 100000000; // 10^8

int main() {
    // Sieve of Eratosthenes
    vector<bool> is_prime(LIMIT + 1, true);
    is_prime[0] = is_prime[1] = false;
    for (int i = 2; (long long)i * i <= LIMIT; i++) {
        if (is_prime[i]) {
            for (int j = i * i; j <= LIMIT; j += i)
                is_prime[j] = false;
        }
    }

    long long ans = 0;

    // Enumerate x, k, y
    for (long long x = 2; x * x <= LIMIT; x++) {
        for (long long k = 1; k * x * x <= LIMIT; k++) {
            long long c1 = k * x * x; // c + 1
            if (c1 - 1 < 2) continue;
            if (!is_prime[c1 - 1]) continue;

            for (long long y = 1; y < x; y++) {
                // Skip if both even
                if (x % 2 == 0 && y % 2 == 0) continue;

                long long a1 = k * y * y; // a + 1
                long long b1 = k * x * y; // b + 1

                if (a1 < 2 || b1 < 2) continue;
                if (a1 - 1 < 2) continue;

                if (!is_prime[a1 - 1]) continue;
                if (!is_prime[b1 - 1]) continue;

                // Check gcd(x, y) == 1
                if (__gcd(x, y) != 1) continue;

                ans += (a1 - 1) + (b1 - 1) + (c1 - 1);
            }
        }
    }

    cout << ans << endl;
    return 0;
}