All Euler problems
Project Euler

Zeckendorf Representation

Every positive integer has a unique Zeckendorf representation as a sum of non-consecutive Fibonacci numbers. Let z(n) denote the number of terms in this representation. For example, z(5) = 1, z(14)...

Source sync Apr 19, 2026
Problem #0297
Level Level 08
Solved By 3,182
Languages C++, Python
Answer 2252639041804718029
Length 357 words
sequencenumber_theoryrecursion

Problem Statement

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

Each new term in the Fibonacci sequence is generated by adding the previous two terms.

Starting with \(1\) and \(2\), the first \(10\) terms will be: \(1, 2, 3, 5, 8, 13, 21, 34, 55, 89\).

Every positive integer can be uniquely written as a sum of nonconsecutive terms of the Fibonacci sequence. For example, \(100 = 3 + 8 + 89\).

Such a sum is called the Zeckendorf representation of the number.

For any integer \(n > 0\), let \(z(n)\) be the number of terms in the Zeckendorf representation of \(n\).

Thus, \(z(5) = 1\), \(z(14) = 2\), \(z(100) = 3\) etc.

Also, for \(0 < n < 10^6\), \(\sum z(n) = 7894453\).

Find \(\sum z(n)\) for \(0 < n < 10^{17}\).

Problem 297: Zeckendorf Representation

Mathematical Foundation

We use the Fibonacci sequence F1=1,F2=2,F3=3,F4=5,F5=8,F_1 = 1, F_2 = 2, F_3 = 3, F_4 = 5, F_5 = 8, \ldots defined by Fk=Fk1+Fk2F_k = F_{k-1} + F_{k-2} with F1=1,F2=2F_1 = 1, F_2 = 2.

Theorem 1 (Zeckendorf’s Theorem). Every positive integer nn has a unique representation n=iSFin = \sum_{i \in S} F_i where SNS \subset \mathbb{N} and SS contains no two consecutive indices.

Proof. (Existence) By strong induction. For n=1=F1n = 1 = F_1, the result holds. For n>1n > 1, let FkF_k be the largest Fibonacci number n\leq n. Then 0nFk<Fk10 \leq n - F_k < F_{k-1} (since Fk+1=Fk+Fk1>nF_{k+1} = F_k + F_{k-1} > n). By induction, nFkn - F_k has a Zeckendorf representation using Fibonacci numbers Fk2\leq F_{k-2} (no Fk1F_{k-1} appears because nFk<Fk1n - F_k < F_{k-1}), so the representation is non-consecutive.

(Uniqueness) Suppose n=iSFi=jTFjn = \sum_{i \in S} F_i = \sum_{j \in T} F_j with STS \neq T. Let kk be the largest index in STS \triangle T. WLOG kSTk \in S \setminus T. Then jT,j>kFj=0\sum_{j \in T, j > k} F_j = 0 (since kk is the largest in the symmetric difference and elements >k> k match). But jT,jk2FjFk2+Fk4+<Fk\sum_{j \in T, j \leq k-2} F_j \leq F_{k-2} + F_{k-4} + \cdots < F_k (by a standard Fibonacci identity), a contradiction since the TT-sum must account for FkF_k. \square

Theorem 2 (Recurrence for S(N)S(N) at Fibonacci Boundaries). Define S(N)=n=1N1z(n)S(N) = \sum_{n=1}^{N-1} z(n). Then

S(Fk+1)=S(Fk)+S(Fk1)+Fk1.S(F_{k+1}) = S(F_k) + S(F_{k-1}) + F_{k-1}.

Proof. The integers in [1,Fk+1)[1, F_{k+1}) split into [1,Fk)[1, F_k) and [Fk,Fk+1)[F_k, F_{k+1}). The first group contributes S(Fk)S(F_k).

For the second group: each integer n[Fk,Fk+1)n \in [F_k, F_{k+1}) can be written uniquely as n=Fk+mn = F_k + m where 0m<Fk10 \leq m < F_{k-1}. Since nFkn \geq F_k and n<Fk+1=Fk+Fk1n < F_{k+1} = F_k + F_{k-1}, we have m=nFk[0,Fk1)m = n - F_k \in [0, F_{k-1}). The Zeckendorf representation of nn is FkF_k plus the Zeckendorf representation of mm (which uses only F1,,Fk2F_1, \ldots, F_{k-2} since m<Fk1m < F_{k-1}, ensuring no consecutive indices with FkF_k).

Thus z(n)=1+z(m)z(n) = 1 + z(m) for m>0m > 0, and z(Fk)=1z(F_k) = 1 (when m=0m = 0). The total contribution is:

m=0Fk11(1+z(m))=Fk1+m=1Fk11z(m)=Fk1+S(Fk1).\sum_{m=0}^{F_{k-1}-1} (1 + z(m)) = F_{k-1} + \sum_{m=1}^{F_{k-1}-1} z(m) = F_{k-1} + S(F_{k-1}).

Hence S(Fk+1)=S(Fk)+Fk1+S(Fk1)S(F_{k+1}) = S(F_k) + F_{k-1} + S(F_{k-1}). \square

Theorem 3 (General Recursion). For FkN<Fk+1F_k \leq N < F_{k+1}:

S(N)=S(Fk)+(NFk)+S(NFk).S(N) = S(F_k) + (N - F_k) + S(N - F_k).

Proof. Split [1,N)[1, N) into [1,Fk)[1, F_k) and [Fk,N)[F_k, N). The first contributes S(Fk)S(F_k). For the second, each n[Fk,N)n \in [F_k, N) has z(n)=1+z(nFk)z(n) = 1 + z(n - F_k) as above. There are NFkN - F_k such integers, each contributing the extra 11 for the FkF_k term, plus z(nFk)z(n - F_k). The residuals nFkn - F_k range over [0,NFk)[0, N - F_k), contributing S(NFk)S(N - F_k). \square

Lemma 1 (Recursion Depth). The recursion in Theorem 3 terminates in O(logφN)O(\log_\varphi N) steps, where φ=(1+5)/2\varphi = (1+\sqrt{5})/2.

Proof. At each step, NN is replaced by NFkN - F_k where FkN/φF_k \geq N/\varphi (since Fk>NFk1NN/φ=N/φ2F_k > N - F_{k-1} \geq N - N/\varphi = N/\varphi^2, and actually FkN/φF_k \geq N/\varphi follows from Fk+1>NF_{k+1} > N and Fk+1/FkφF_{k+1}/F_k \to \varphi). Thus NFkN(11/φ)=N/φ2N - F_k \leq N(1 - 1/\varphi) = N/\varphi^2, and after jj steps, NN is reduced to at most N/φ2jN/\varphi^{2j}. The recursion terminates when N<F2=2N < F_2 = 2, requiring O(logφN)O(\log_\varphi N) steps. \square

Editorial

Fibonacci: F[0]=1, F[1]=2, F[2]=3, F[3]=5, … S(N) = sum of z(n) for n in [1, N). At Fibonacci boundaries: S(F[k+1]) = S(F[k]) + S(F[k-1]) + F[k-1] General recursion (F[k] <= N < F[k+1]): S(N) = S(F[k]) + (N - F[k]) + S(N - F[k]). We precompute Fibonacci numbers and S(F_k). Finally, recursive computation of S(N).

Pseudocode

Precompute Fibonacci numbers and S(F_k)
Recursive computation of S(N)

Complexity Analysis

  • Time: O(logN)O(\log N) for precomputing logφN83\sim \log_\varphi N \approx 83 Fibonacci numbers and their SS-values, plus O(logN)O(\log N) recursive steps.
  • Space: O(logN)O(\log N) for storing Fibonacci numbers and S(Fk)S(F_k) values (about 83 entries for N=1017N = 10^{17}).

Answer

2252639041804718029\boxed{2252639041804718029}

Code

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

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

// Problem 297: Zeckendorf Representation
//
// Find sum of z(n) for 0 < n < 10^17, where z(n) = number of terms
// in the Zeckendorf representation of n.
//
// Fibonacci: F[1]=1, F[2]=2, F[3]=3, F[4]=5, ...
//
// S(N) = sum of z(n) for n in [1, N).
//
// At Fibonacci boundaries:
//   S(F[k+1]) = S(F[k]) + S(F[k-1]) + F[k-1]
//
// General recursion (for F[k] <= N < F[k+1]):
//   S(N) = S(F[k]) + (N - F[k]) + S(N - F[k])
//
// Each recursive call reduces N, and the sequence of remainders follows
// a Zeckendorf-like decomposition, terminating in O(log N) steps.

int main(){
    long long N = 100000000000000000LL; // 10^17

    // Generate Fibonacci numbers: F[1]=1, F[2]=2, F[3]=3, ...
    vector<long long> F;
    F.push_back(1);
    F.push_back(2);
    while (F.back() < N) {
        F.push_back(F[F.size()-1] + F[F.size()-2]);
    }
    int M = F.size(); // F[0]..F[M-1] = F_1..F_M

    // Precompute S(F[k]) for k = 1..M
    // S(F[1]) = S(1) = 0 (sum over empty range [1,1))
    // S(F[2]) = S(2) = z(1) = 1
    // S(F[k+1]) = S(F[k]) + S(F[k-1]) + F[k-1]
    // Using 0-indexed: S_fib[i] = S(F[i])
    vector<long long> SF(M + 1, 0);
    // SF[0] = S(F[0]) = S(1) = 0
    // SF[1] = S(F[1]) = S(2) = z(1) = 1
    SF[0] = 0;
    if (M >= 2) SF[1] = 1;
    for (int i = 2; i < M; i++) {
        // S(F[i]) = S(F[i-1]) + S(F[i-2]) + F[i-2]
        // In 0-indexed: F[i] corresponds to F_{i+1}, F[i-2] = F_{i-1}
        // Wait, let me re-index carefully.
        // F[0] = F_1 = 1, F[1] = F_2 = 2, F[2] = F_3 = 3, ...
        // S(F_{k+1}) = S(F_k) + S(F_{k-1}) + F_{k-1}
        // In 0-indexed: S(F[i]) = S(F[i-1]) + S(F[i-2]) + F[i-2]
        SF[i] = SF[i-1] + SF[i-2] + F[i-2];
    }

    // Now compute S(N) recursively
    // S(N): find largest F[k] <= N, then S(N) = SF[k] + (N - F[k]) + S(N - F[k])
    // where k is 0-indexed into F array.
    // Note: N - F[k] < F[k-1], so recursion terminates.

    function<long long(long long)> S = [&](long long n) -> long long {
        if (n <= 1) return 0; // S(1) = 0, S(0) = 0
        // Find largest F[k] <= n
        // F is sorted, use upper_bound
        int k = (int)(upper_bound(F.begin(), F.end(), n) - F.begin()) - 1;
        // F[k] <= n < F[k+1]
        if (F[k] == n) return SF[k];
        return SF[k] + (n - F[k]) + S(n - F[k]);
    };

    cout << S(N) << endl;
    return 0;
}