All Euler problems
Project Euler

Geometric Series Truncation

Let S(r, n) = sum_(k=0)^n r^k for integer r >= 2. Find sum_(r=2)^100 S(r, r) mod (10^9+7).

Source sync Apr 19, 2026
Problem #0911
Level Level 36
Solved By 196
Languages C++, Python
Answer 5679.934966
Length 221 words
modular_arithmeticnumber_theoryalgebra

Problem Statement

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

An irrational number $x$ can be uniquely expressed as a continued fraction $[a_0; a_1,a_2,a_3,\dots]$: $$ x=a_{0}+\cfrac{1}{a_1+\cfrac{1}{a_2+\cfrac{1}{a_3+\ddots}}} $$ where $a_0$ is an integer and $a_1,a_2,a_3,\dots$ are positive integers.

Define $k_j(x)$ to be the geometric mean of $a_1,a_2,\dots,a_j$.

That is, $k_j(x)=(a_1a_2 \cdots a_j)^{1/j}$.

Also define $k_\infty(x)=\lim_{j\to \infty} k_j(x)$.

Khinchin proved that almost all irrational numbers $x$ have the same value of $k_\infty(x)\approx2.685452\dots$ known as Khinchin's constant. However, there are some exceptions to this rule.

For $n\geq 0$ define $$\rho_n = \sum_{i=0}^{\infty} \frac{2^n}{2^{2^i}} $$ For example $\rho_2$, with continued fraction beginning $[3; 3, 1, 3, 4, 3, 1, 3,\dots]$, has $k_\infty(\rho_2)\approx2.059767$.

Find the geometric mean of $k_{\infty}(\rho_n)$ for $0\leq n\leq 50$, giving your answer rounded to six digits after the decimal point.

Problem 911: Geometric Series Truncation

Mathematical Foundation

Theorem 1 (Geometric Series). For r1r \ne 1 and non-negative integer nn,

S(r,n)=k=0nrk=rn+11r1.S(r, n) = \sum_{k=0}^{n} r^k = \frac{r^{n+1} - 1}{r - 1}.

Proof. Let S=k=0nrkS = \sum_{k=0}^{n} r^k. Then

rS=k=0nrk+1=k=1n+1rk.rS = \sum_{k=0}^{n} r^{k+1} = \sum_{k=1}^{n+1} r^k.

Subtracting the original sum:

rSS=rn+1r0=rn+11.rS - S = r^{n+1} - r^0 = r^{n+1} - 1.

Since r1r \ne 1, we divide both sides by (r1)(r - 1) to obtain S=(rn+11)/(r1)S = (r^{n+1} - 1)/(r - 1). \square

Theorem 2 (Fermat’s Little Theorem). For a prime pp and integer aa with gcd(a,p)=1\gcd(a, p) = 1,

ap11(modp),a^{p-1} \equiv 1 \pmod{p},

and consequently a1ap2(modp)a^{-1} \equiv a^{p-2} \pmod{p}.

Proof. Consider the map ϕa:(Z/pZ)(Z/pZ)\phi_a : (\mathbb{Z}/p\mathbb{Z})^* \to (\mathbb{Z}/p\mathbb{Z})^* defined by ϕa(x)=ax\phi_a(x) = ax. Since gcd(a,p)=1\gcd(a, p) = 1, this map is injective on the finite set {1,2,,p1}\{1, 2, \ldots, p-1\}, hence bijective. Therefore

x=1p1(ax)=x=1p1x,\prod_{x=1}^{p-1} (ax) = \prod_{x=1}^{p-1} x,

which gives ap1(p1)!(p1)!(modp)a^{p-1} \cdot (p-1)! \equiv (p-1)! \pmod{p}. Since gcd((p1)!,p)=1\gcd((p-1)!, p) = 1, we cancel to obtain ap11(modp)a^{p-1} \equiv 1 \pmod{p}. Multiplying both sides by a1a^{-1} yields ap2a1(modp)a^{p-2} \equiv a^{-1} \pmod{p}. \square

Lemma 1. For 2r1002 \le r \le 100 and p=109+7p = 10^9 + 7, the modular inverse (r1)1modp(r-1)^{-1} \bmod p exists.

Proof. We have 1r199<p1 \le r - 1 \le 99 < p, so r1≢0(modp)r - 1 \not\equiv 0 \pmod{p}. Since pp is prime, gcd(r1,p)=1\gcd(r-1, p) = 1, and the inverse exists by Theorem 2. \square

Theorem 3 (Correctness). The value r=2100S(r,r)modp\sum_{r=2}^{100} S(r, r) \bmod p equals r=2100[(rr+11)(r1)p2]modp\sum_{r=2}^{100} \bigl[(r^{r+1} - 1) \cdot (r-1)^{p-2}\bigr] \bmod p.

Proof. By Theorem 1, S(r,r)=(rr+11)/(r1)S(r, r) = (r^{r+1} - 1)/(r - 1) over Z\mathbb{Z}. By Lemma 1, (r1)1(r-1)^{-1} exists modulo pp, and by Theorem 2, (r1)1(r1)p2(modp)(r-1)^{-1} \equiv (r-1)^{p-2} \pmod{p}. The natural ring homomorphism ZZ/pZ\mathbb{Z} \to \mathbb{Z}/p\mathbb{Z} preserves addition and multiplication, so

S(r,r)modp(rr+11)(r1)p2(modp).S(r, r) \bmod p \equiv (r^{r+1} - 1) \cdot (r-1)^{p-2} \pmod{p}.

Summing over r=2,,100r = 2, \ldots, 100 and reducing modulo pp gives the result. \square

Editorial

S(r, n) = sum_{k=0}^{n} r^k = (r^{n+1} - 1) / (r - 1). Find sum_{r=2}^{100} S(r, r) mod 10^9+7. We enumerate the admissible parameter range, discard candidates that violate the derived bounds or arithmetic constraints, and update the final set or total whenever a candidate passes the acceptance test.

Pseudocode

    p = 10^9 + 7
    total = 0
    For r from 2 to 100:
        numerator = (pow_mod(r, r+1, p) - 1 + p) mod p
        denominator_inv = pow_mod(r - 1, p - 2, p)
        total = (total + numerator * denominator_inv) mod p
    Return total

    result = 1
    base = base mod mod
    While exp > 0:
        if exp is odd:
            result = (result * base) mod mod
        exp = exp >> 1
        base = (base * base) mod mod
    Return result

Complexity Analysis

  • Time: O(Rlogp)O(R \log p) where R=99R = 99. Each of the 99 terms requires two modular exponentiations: rr+1modpr^{r+1} \bmod p in O(logr)O(\log r) and (r1)p2modp(r-1)^{p-2} \bmod p in O(logp)O(\log p). The dominant cost is O(Rlogp)99×302970O(R \log p) \approx 99 \times 30 \approx 2970 modular multiplications.
  • Space: O(1)O(1). Only a constant number of variables are maintained.

Answer

5679.934966\boxed{5679.934966}

Code

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

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

/*
 * Problem 911: Geometric Series Truncation
 *
 * S(r, n) = sum_{k=0}^{n} r^k = (r^{n+1} - 1) / (r - 1)
 * Find sum_{r=2}^{100} S(r, r) mod 10^9+7.
 *
 * Two methods:
 *   1. Closed-form: S(r,r) = (r^{r+1} - 1) * (r-1)^{-1} mod p
 *   2. Direct summation: iterate powers 1, r, r^2, ..., r^r
 *
 * Modular inverse via Fermat: (r-1)^{p-2} mod p.
 */

const long long MOD = 1e9 + 7;

long long power(long long base, long long exp, long long mod) {
    long long result = 1;
    base %= mod;
    while (exp > 0) {
        if (exp & 1) result = result * base % mod;
        base = base * base % mod;
        exp >>= 1;
    }
    return result;
}

/* Method 1: Closed-form with Fermat inverse */
long long solve_closed() {
    long long total = 0;
    for (int r = 2; r <= 100; r++) {
        long long num = (power(r, r + 1, MOD) - 1 + MOD) % MOD;
        long long inv = power(r - 1, MOD - 2, MOD);
        total = (total + num % MOD * inv % MOD) % MOD;
    }
    return total;
}

/* Method 2: Direct summation */
long long solve_direct() {
    long long total = 0;
    for (int r = 2; r <= 100; r++) {
        long long s = 0, rk = 1;
        for (int k = 0; k <= r; k++) {
            s = (s + rk) % MOD;
            rk = rk * r % MOD;
        }
        total = (total + s) % MOD;
    }
    return total;
}

int main() {
    long long ans1 = solve_closed();
    long long ans2 = solve_direct();

    assert(ans1 == ans2);

    // Verify small exact values
    // S(2,2) = 7, S(3,3) = 40, S(4,4) = 341
    assert((power(2, 3, MOD) - 1 + MOD) % MOD * power(1, MOD - 2, MOD) % MOD == 7);
    assert((power(3, 4, MOD) - 1 + MOD) % MOD * power(2, MOD - 2, MOD) % MOD == 40);

    cout << ans1 << endl;
    return 0;
}