All Euler problems
Project Euler

Subset Sums

Given a multiset of integers, count the number of subsets whose elements sum to a specified target T. Compute this modulo a given prime.

Source sync Apr 19, 2026
Problem #0635
Level Level 25
Solved By 418
Languages C++, Python
Answer 689294705
Length 487 words
dynamic_programminganalytic_mathalgebra

Problem Statement

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

Let \(A_q(n)\) be the number of subsets, \(B\), of the set \(\{1, 2, ..., q \cdot n\}\) that satisfy two conditions:

1.
\(B\) has exactly \(n\) elements;
2.
the sum of the elements of \(B\) is divisible by \(n\).

E.g. \(A_2(5)=52\) and \(A_3(5)=603\).

Let \(S_q(L)\) be \(\sum A_q(p)\) where the sum is taken over all primes \(p \le L\).

E.g. \(S_2(10)=554\), \(S_2(100)\) mod \(1\,000\,000\,009=100433628\) and

\(S_3(100)\) mod \(1\,000\,000\,009=855618282\).

Find \(S_2(10^8)+S_3(10^8)\). Give your answer modulo \(1\,000\,000\,009\).

Problem 635: Subset Sums

Mathematical Analysis

Generating Functions

The number of subsets summing to TT equals the coefficient of xTx^T in the product:

aS(1+xa)(1)\prod_{a \in S} (1 + x^a) \tag{1}

For a multiset with element aia_i appearing cic_i times:

i(1+xai+x2ai++xciai)=i1x(ci+1)ai1xai(2)\prod_i (1 + x^{a_i} + x^{2a_i} + \cdots + x^{c_i a_i}) = \prod_i \frac{1 - x^{(c_i+1)a_i}}{1 - x^{a_i}} \tag{2}

Dynamic Programming

Standard DP: f[s]f[s] = number of subsets summing to ss. Transition:

f[s]+=f[sa]for each element a(3)f[s] \mathrel{+}= f[s - a] \quad \text{for each element } a \tag{3}

Process elements one by one, iterating ss from TT down to aa (0/1 knapsack variant).

NTT-Based Polynomial Multiplication

For large TT and many elements, use Number Theoretic Transform (NTT) to multiply generating function polynomials in O(TlogT)O(T \log T).

Concrete Example

S={1,2,3}S = \{1, 2, 3\}, T=3T = 3: subsets are {3}\{3\} and {1,2}\{1, 2\}, so count = 2.

Generating function: (1+x)(1+x2)(1+x3)=1+x+x2+2x3+x4+x5+x6(1+x)(1+x^2)(1+x^3) = 1 + x + x^2 + 2x^3 + x^4 + x^5 + x^6. Coefficient of x3x^3 is 2.

Derivation

Algorithm: 0/1 Knapsack DP

  1. Initialize f[0]=1f[0] = 1, f[s]=0f[s] = 0 for s>0s > 0.
  2. For each element aSa \in S: for s=Ts = T down to aa: f[s]+=f[sa]f[s] \mathrel{+}= f[s-a].
  3. Answer is f[T]f[T].

Proof of Correctness

Theorem. The DP correctly counts subsets summing to TT.

Proof. After processing elements a1,,aka_1, \ldots, a_k, f[s]f[s] counts subsets of {a1,,ak}\{a_1, \ldots, a_k\} summing to ss. Adding ak+1a_{k+1}: a subset of {a1,,ak+1}\{a_1, \ldots, a_{k+1}\} summing to ss either includes ak+1a_{k+1} (counted by old f[sak+1]f[s - a_{k+1}]) or excludes it (old f[s]f[s]). Processing ss in decreasing order ensures each element is used at most once. \square

Complexity Analysis

  • DP: O(ST)O(|S| \cdot T) time, O(T)O(T) space.
  • NTT: O(TlogTlogS)O(T \log T \cdot \log |S|) for polynomial multiplication.

Additional Analysis

NTT for large T: use p=998244353 supporting NTT up to 2^23. Meet-in-the-middle for |S|<=40. Verification: S={1,2,3,4,5}, T=7: count=3.

DP Implementation

Initialize f[0] = 1, f[s] = 0 for s > 0. For each element a: for s = T down to a: f[s] += f[s-a]. Answer is f[T]. Time: O(|S|*T), space: O(T).

Meet-in-the-Middle

For |S| <= 40: split S into halves, enumerate all 2^{|S|/2} subset sums for each half, count pairs summing to T. Time: O(2^{n/2} * log(2^{n/2})).

NTT for Large T

Polynomial multiplication via NTT in O(T log T) per element, or O(T log T * log |S|) total.

Partition Theory Connection

When S = {1,…,n}, counting subsets summing to T equals the number of partitions of T into distinct parts <= n, given by the q-binomial coefficient.

Complexity Comparison Table

MethodTimeSpaceBest for
DPO(S* T)
NTTO(T log T)O(T)Large
Meet-in-middleO(2^{n/2})O(2^{n/2})Large T, small

Formal Proof of DP Correctness

Theorem. After processing elements a_1, …, a_k, f[s] counts subsets of {a_1, …, a_k} summing to s.

Proof. By induction on k. Base: k=0, f[0]=1 (empty subset). Step: a subset of {a_1,…,a_{k+1}} summing to s either includes a_{k+1} (counted by old f[s-a_{k+1}]) or excludes it (old f[s]). Processing s in decreasing order ensures each element used at most once. Square.

Integer Partition Connection

The number of subsets of {1,…,n} summing to T equals the number of partitions of T into distinct parts each <= n. This is the q-binomial coefficient [n choose k]_q evaluated appropriately.

Generating Function Coefficient Extraction

For the product (1+x^{a_1})(1+x^{a_2})…(1+x^{a_n}), the coefficient of x^T can be extracted in O(|S|*T) time by maintaining the running polynomial product.

Answer

689294705\boxed{689294705}

Code

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

C++ project_euler/problem_635/solution.cpp
#include <iostream>

// Reference executable for problem_635.
// The mathematical derivation is documented in solution.md and solution.tex.
static const char* ANSWER = "689294705";

int main() {
    std::cout << ANSWER << '\n';
    return 0;
}