All Euler problems
Project Euler

Writing 1/2 as a Sum of Inverse Squares

Find the number of distinct subsets S subseteq {2, 3,..., 80} such that sum_(k in S) (1)/(k^2) = (1)/(2).

Source sync Apr 19, 2026
Problem #0152
Level Level 08
Solved By 3,194
Languages C++, Python
Answer 301
Length 510 words
searchnumber_theorymodular_arithmetic

Problem Statement

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

There are several ways to write the number \(\dfrac {1}{2}\) as a sum of square reciprocals using distinct integers.

For instance, the numbers \(\{2,3,4,5,7,12,15,20,28,35\}\) can be used: \begin {align*} \dfrac {1}{2} &= \dfrac {1}{2^2} + \dfrac {1}{3^2} + \dfrac {1}{4^2} + \dfrac {1}{5^2} +\\ &\quad \dfrac {1}{7^2} + \dfrac {1}{12^2} + \dfrac {1}{15^2} + \dfrac {1}{20^2} +\\ &\quad \dfrac {1}{28^2} + \dfrac {1}{35^2} \end {align*}

In fact, only using integers between \(2\) and \(45\) inclusive, there are exactly three ways to do it, the remaining two being: \(\{2,3,4,6,7,9,10,20,28,35,36,45\}\) and \(\{2,3,4,6,7,9,12,15,28,30,35,36,45\}\).

How many ways are there to write \(\dfrac {1}{2}\) as a sum of reciprocals of squares using distinct integers between \(2\) and \(80\) inclusive?

Problem 152: Writing 1/2 as a Sum of Inverse Squares

Mathematical Development

Definition 1. Let L=lcm(k2:2k80)L = \operatorname{lcm}(k^2 : 2 \le k \le 80). For any subset S{2,,80}S \subseteq \{2, \ldots, 80\}, define Σ(S)=kSL/k2\Sigma(S) = \sum_{k \in S} L / k^2, so the target equation becomes Σ(S)=L/2\Sigma(S) = L/2.

Theorem 1 (Large Prime Elimination). Let pp be a prime with 40<p8040 < p \le 80. Then pSp \notin S for any valid subset SS.

Proof. Since p>40p > 40, the only multiple of pp in {2,,80}\{2, \ldots, 80\} is pp itself (as 2p>802p > 80). Consider the pp-adic valuation of the cleared equation Σ(S)=L/2\Sigma(S) = L/2. We have vp(L)=2v_p(L) = 2 (from p2Lp^2 \mid L and p3Lp^3 \nmid L, since p26400Lp^2 \le 6400 \le L but p2p^2 appears only once in the range). For kpk \neq p with pkp \nmid k, vp(L/k2)=vp(L)=2v_p(L/k^2) = v_p(L) = 2. For k=pk = p, vp(L/p2)=vp(L)2=0v_p(L/p^2) = v_p(L) - 2 = 0.

Suppose pSp \in S. Then vp(Σ(S))=min(vp(L/p2),minkS{p}vp(L/k2))=min(0,2)=0v_p(\Sigma(S)) = \min(v_p(L/p^2), \min_{k \in S \setminus \{p\}} v_p(L/k^2)) = \min(0, 2) = 0. But vp(L/2)=vp(L)vp(2)=2v_p(L/2) = v_p(L) - v_p(2) = 2 (since p41>2p \ge 41 > 2). This gives 0=vp(Σ(S))vp(L/2)=20 = v_p(\Sigma(S)) \neq v_p(L/2) = 2, a contradiction (more precisely, the term with vp=0v_p = 0 cannot cancel since it is the unique term with minimal pp-adic valuation). Hence pSp \notin S.

This eliminates {41,43,47,53,59,61,67,71,73,79}\{41, 43, 47, 53, 59, 61, 67, 71, 73, 79\}. \square

Theorem 2 (Paired Prime Elimination). Let pp be a prime with 26<p4026 < p \le 40, and let Mp={k{2,,80}:pk}M_p = \{k \in \{2, \ldots, 80\} : p \mid k\}. The subset SMpS \cap M_p must satisfy a modular constraint: the partial sum kSMpL/k2\sum_{k \in S \cap M_p} L/k^2 must be congruent to a specific residue modulo pvp(L)p^{v_p(L)}. For each such pp, exhaustive enumeration of the (at most 2Mp2^{|M_p|}) subsets of MpM_p determines which elements can appear.

Proof. Write the cleared equation as Σ(S)=L/2\Sigma(S) = L/2. Partition S=(SMp)(SMp)S = (S \cap M_p) \sqcup (S \setminus M_p). For every kSMpk \in S \setminus M_p, we have pkp \nmid k, so vp(L/k2)vp(L)v_p(L/k^2) \ge v_p(L). Hence kSMpL/k20(modpvp(L))\sum_{k \in S \setminus M_p} L/k^2 \equiv 0 \pmod{p^{v_p(L)}}. Also vp(L/2)vp(L)v_p(L/2) \ge v_p(L) since p29>2p \ge 29 > 2, so L/20(modpvp(L))L/2 \equiv 0 \pmod{p^{v_p(L)}}.

Therefore kSMpL/k20(modpvp(L))\sum_{k \in S \cap M_p} L/k^2 \equiv 0 \pmod{p^{v_p(L)}}. Since Mp3|M_p| \le 3 for p29p \ge 29 (at most p,2pp, 2p and possibly 3p3p lie in {2,,80}\{2, \ldots, 80\}), the constraint is verified by exhaustive check over at most 23=82^3 = 8 subsets. If no non-empty subset of MpM_p satisfies the congruence, all elements of MpM_p are excluded from SS. \square

Lemma 1 (Reduced Candidate Set). Applying Theorems 1 and 2 systematically for all primes pp from 79 down to 2, the candidate set reduces from 79 elements to approximately 36 elements, with certain elements forced to appear in specific groups.

Proof. Direct computation of modular constraints for each prime. The eliminated elements include all multiples of primes 29\ge 29 that fail the congruence test, as well as various multiples of smaller primes constrained by similar pp-adic arguments. \square

Theorem 3 (Correctness of DFS Enumeration). The valid subsets are enumerated by depth-first search over the reduced candidate set with integer arithmetic and the following pruning rules:

  1. If the partial sum exceeds L/2L/2, prune (remaining terms are positive).
  2. If the partial sum plus the sum of all remaining candidates is less than L/2L/2, prune (insufficient capacity).

The search is exhaustive over the non-pruned branches and therefore returns the exact count.

Proof. Let c1<c2<<cmc_1 < c_2 < \cdots < c_m be the sorted candidates with corresponding values vi=L/ci2v_i = L / c_i^2. The DFS considers, for each index ii, whether to include cic_i in SS. Let Ri=jivjR_i = \sum_{j \ge i} v_j. At any node with partial sum σ\sigma at index ii:

  • If σ>L/2\sigma > L/2: since vj>0v_j > 0 for all jj, adding further elements only increases the sum, so no completion exists.
  • If σ+Ri<L/2\sigma + R_i < L/2: even including all remaining elements cannot reach L/2L/2, so no completion exists.

Both pruning conditions eliminate only infeasible branches. The base case (i=mi = m or σ=L/2\sigma = L/2) is exact. By structural induction on the DFS tree, all valid subsets are found. \square

Editorial

We prime elimination (reduce candidate set). Finally, integer DFS with pruning. We perform a recursive search over the admissible choices, prune branches that violate the derived constraints, and keep only the candidates that satisfy the final condition.

Pseudocode

Prime elimination (reduce candidate set)
Integer DFS with pruning

Complexity Analysis

  • Time: O(2m)O(2^m) in the worst case where m36m \approx 36 is the candidate count. The branch-and-bound pruning dramatically reduces the effective search space; empirically the search completes in under one second.
  • Space: O(m)O(m) for the recursion stack and O(m)O(m) for the precomputed suffix sums.

Answer

301\boxed{301}

Code

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

C++ project_euler/problem_152/solution.cpp
#include <bits/stdc++.h>
using namespace std;
typedef long double ld;

int main() {
    set<int> excluded = {
        79,73,71,67,61,59,53,47,43,41,37,74,31,62,29,58,23,46,69,
        19,38,57,76,34,51,26,65,78,11,22,33,44,55,66,77,49,25,50,
        75,27,54,17,68
    };

    vector<int> candidates;
    for (int k = 2; k <= 80; k++)
        if (excluded.find(k) == excluded.end())
            candidates.push_back(k);

    int n = candidates.size();
    ld target = 0.5L;

    vector<ld> vals(n);
    for (int i = 0; i < n; i++)
        vals[i] = 1.0L / ((ld)candidates[i] * candidates[i]);

    vector<ld> suffix(n + 1, 0);
    for (int i = n - 1; i >= 0; i--)
        suffix[i] = suffix[i + 1] + vals[i];

    int count = 0;
    ld eps = 1e-18L;

    function<void(int, ld)> dfs = [&](int idx, ld current) {
        if (fabsl(current - target) < eps) { count++; return; }
        if (idx >= n) return;
        ld need = target - current;
        if (need < -eps) return;
        if (suffix[idx] < need - eps) return;
        for (int i = idx; i < n; i++) {
            if (vals[i] > need + eps) continue;
            if (suffix[i] < need - eps) return;
            dfs(i + 1, current + vals[i]);
        }
    };

    dfs(0, 0.0L);
    printf("%d\n", count);
    return 0;
}