All Euler problems
Project Euler

Exploring the Number of Different Ways a Number Can Be Expressed as a Sum of Powers of 2

Define f(n) as the number of ways to express n as a sum of powers of 2, where each power of 2 is used at most twice. Find f(10^25).

Source sync Apr 19, 2026
Problem #0169
Level Level 06
Solved By 5,893
Languages C++, Python
Answer 178653872807
Length 323 words
dynamic_programmingrecursionsequence

Problem Statement

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

Define \(f(0)=1\) and \(f(n)\) to be the number of different ways \(n\) can be expressed as a sum of integer powers of \(2\) using each power no more than twice.

For example, \(f(10)=5\) since there are five different ways to express \(10\): \begin {align*} & 1 + 1 + 8\\ & 1 + 1 + 4 + 4\\ & 1 + 1 + 2 + 2 + 4\\ & 2 + 4 + 4\\ & 2 + 8 \end {align*}

What is \(f(10^{25})\)?

Problem 169: Exploring the Number of Different Ways a Number Can Be Expressed as a Sum of Powers of 2

Mathematical Foundation

Definition. f(n)={(c0,c1,c2,):ci{0,1,2},i0ci2i=n}f(n) = |\{(c_0, c_1, c_2, \ldots) : c_i \in \{0, 1, 2\}, \, \sum_{i \geq 0} c_i \cdot 2^i = n\}|.

Theorem 1 (Recurrence for ff). For all n0n \geq 0:

f(n)={1if n=0,f ⁣(n/2)if n is odd,f ⁣(n/2)+f ⁣(n/21)if n is even and n \geq2.f(n) = \begin{cases} 1 & \text{if } n = 0, \\ f\!\left(\lfloor n/2 \rfloor\right) & \text{if n is odd,} \\ f\!\left(n/2\right) + f\!\left(n/2 - 1\right) & \text{if n is even and n \geq 2.} \end{cases}

Proof. Consider the coefficient c0c_0 (the number of times 20=12^0 = 1 is used).

Case nn odd: We need c0c_0 odd, so c0=1c_0 = 1. Then i1ci2i=n1\sum_{i \geq 1} c_i \cdot 2^i = n - 1. Dividing by 2: i1ci2i1=(n1)/2=n/2\sum_{i \geq 1} c_i \cdot 2^{i-1} = (n-1)/2 = \lfloor n/2 \rfloor. Relabeling ci=ci+1c_i' = c_{i+1} gives a representation of n/2\lfloor n/2 \rfloor with each ci{0,1,2}c_i' \in \{0, 1, 2\}. This is a bijection, so f(n)=f(n/2)f(n) = f(\lfloor n/2 \rfloor).

Case nn even: We need c0c_0 even, so c0{0,2}c_0 \in \{0, 2\}.

  • If c0=0c_0 = 0: the remaining sum is nn, so i1ci2i=n\sum_{i \geq 1} c_i \cdot 2^i = n, giving i0ci+12i=n/2\sum_{i \geq 0} c_{i+1} \cdot 2^i = n/2. This contributes f(n/2)f(n/2) representations.
  • If c0=2c_0 = 2: the remaining sum is n2n - 2, so i1ci2i=n2\sum_{i \geq 1} c_i \cdot 2^i = n - 2, giving i0ci+12i=(n2)/2=n/21\sum_{i \geq 0} c_{i+1} \cdot 2^i = (n-2)/2 = n/2 - 1. This contributes f(n/21)f(n/2 - 1) representations (valid since n2n \geq 2 ensures n/210n/2 - 1 \geq 0).

Total: f(n)=f(n/2)+f(n/21)f(n) = f(n/2) + f(n/2 - 1). \square

Theorem 2 (Subproblem count). The memoized computation of f(n)f(n) encounters at most O(log2n)O(\log^2 n) distinct subproblems.

Proof. At recursion depth dd, the argument has the form n/2dj\lfloor n / 2^d \rfloor - j for some integer jj with 0jd0 \leq j \leq d. This is because each “even” branch produces two subproblems at argument n/2d+1(something)j\lfloor n/2^{d+1} \rfloor \cdot \text{(something)} - j', and the offset jj increases by at most 1 per even step. At depth dd, there are at most d+1d + 1 possible values of jj, giving at most d=0log2n(d+1)=O(log2n)\sum_{d=0}^{\lfloor \log_2 n \rfloor} (d + 1) = O(\log^2 n) distinct subproblems. \square

Lemma 1 (Base cases). f(0)=1f(0) = 1 (the empty sum) and f(1)=1f(1) = 1 (only c0=1c_0 = 1, all others 0).

Proof. f(0)f(0): the unique representation is ci=0c_i = 0 for all ii. f(1)f(1): c0=1c_0 = 1 is forced (only way to get an odd sum); then the remaining sum is 0, which has a unique representation. \square

Lemma 2 (Correctness for n=1025n = 10^{25}). The recursion terminates since each step replaces nn by n/2\lfloor n/2 \rfloor or n/21\lfloor n/2 \rfloor - 1, strictly decreasing nn until reaching the base cases. The recursion depth is log2(1025)=84\lceil \log_2(10^{25}) \rceil = 84.

Proof. log2(1025)=25log21025×3.3219=83.05\log_2(10^{25}) = 25 \log_2 10 \approx 25 \times 3.3219 = 83.05, so the recursion depth is 84. \square

Editorial

each power used at most twice. Find f(10^25). Recurrence: f(0) = 1 f(n) = f(n//2) if n is odd f(n) = f(n//2) + f(n//2-1) if n is even. We else.

Pseudocode

if n is odd
else

Complexity Analysis

  • Time: O(log2n)O(\log^2 n) subproblems, each requiring O(1)O(1) work (plus big-integer arithmetic for the values, which are O(logn)O(\log n) bits). Total: O(log2nM(logn))O(\log^2 n \cdot M(\log n)) where MM is multiplication cost, but since the values of ff are polynomially bounded in nn, O(log3n)O(\log^3 n) suffices.
  • Space: O(log2n)O(\log^2 n) for the memoization table.

For n=1025n = 10^{25}: depth 84\approx 84, subproblems 842/23,528\leq 84^2 / 2 \approx 3{,}528.

Answer

178653872807\boxed{178653872807}

Code

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

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

/*
 * Problem 169: Number of ways to express n as sum of powers of 2,
 * each used at most twice. Find f(10^25).
 *
 * Recurrence:
 *   f(0) = 1
 *   f(n) = f(n/2)             if n is odd
 *   f(n) = f(n/2) + f(n/2-1)  if n is even
 *
 * We use Python-style big integers via strings or __int128.
 * Since 10^25 fits in unsigned 128-bit, we use __int128.
 */

typedef __int128 lll;

map<lll, long long> memo;

long long f(lll n) {
    if (n == 0) return 1;
    auto it = memo.find(n);
    if (it != memo.end()) return it->second;

    long long result;
    if (n % 2 == 1) {
        result = f(n / 2);
    } else {
        result = f(n / 2) + f(n / 2 - 1);
    }
    memo[n] = result;
    return result;
}

int main(){
    // 10^25
    lll n = 1;
    for (int i = 0; i < 25; i++) n *= 10;

    cout << (long long)f(n) << endl;
    return 0;
}