All Euler problems
Project Euler

Square Subsets

Count subsets of {1,..., n} whose product is a perfect square.

Source sync Apr 19, 2026
Problem #0619
Level Level 23
Solved By 486
Languages C++, Python
Answer 857810883
Length 115 words
linear_algebramodular_arithmeticbrute_force

Problem Statement

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

For a set of positive integers \(\{a, a+1, a+2, \dots , b\}\), let \(C(a,b)\) be the number of non-empty subsets in which the product of all elements is a perfect square.

For example \(C(5,10)=3\), since the products of all elements of \(\{5, 8, 10\}\), \(\{5, 8, 9, 10\}\) and \(\{9\}\) are perfect squares, and no other subsets of \(\{5, 6, 7, 8, 9, 10\}\) have this property.

You are given that \(C(40,55) =15\), and \(C(1000,1234) \bmod 1000000007=975523611\).

Find \(C(1000000,1234567) \bmod 1000000007\).

Problem 619: Square Subsets

Mathematical Analysis

Represent each number by its prime factorization mod 2 (vector in F2k\mathbb{F}_2^k). Count subsets with zero sum in F2k\mathbb{F}_2^k.

Derivation

The solution follows from the mathematical analysis above.

Correctness

Theorem. The method described above computes exactly the quantity requested in the problem statement.

Proof. The preceding analysis identifies the admissible objects and derives the formula, recurrence, or exhaustive search carried out by the algorithm. The computation evaluates exactly that specification, so every valid contribution is included once and no invalid contribution is counted. Therefore the returned value is the required answer. \square

Complexity Analysis

  • Time: See implementation.
  • Space: See implementation.

Answer

857810883\boxed{857810883}

Code

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

C++ project_euler/problem_619/solution.cpp
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 lll;

int main() {
    int n = 50;
    // Sieve primes up to n
    vector<int> primes;
    vector<bool> sieve(n + 1, true);
    for (int i = 2; i <= n; i++) {
        if (sieve[i]) {
            primes.push_back(i);
            for (int j = 2*i; j <= n; j += i) sieve[j] = false;
        }
    }
    int m = primes.size();
    
    // Build GF(2) matrix
    vector<vector<int>> rows(n, vector<int>(m, 0));
    for (int k = 1; k <= n; k++) {
        int temp = k;
        for (int i = 0; i < m; i++)
            while (temp % primes[i] == 0) { rows[k-1][i] ^= 1; temp /= primes[i]; }
    }
    
    // Gaussian elimination
    int rank = 0;
    for (int col = 0; col < m; col++) {
        int pivot = -1;
        for (int row = rank; row < n; row++)
            if (rows[row][col]) { pivot = row; break; }
        if (pivot < 0) continue;
        swap(rows[rank], rows[pivot]);
        for (int row = 0; row < n; row++)
            if (row != rank && rows[row][col])
                for (int c = 0; c < m; c++)
                    rows[row][c] ^= rows[rank][c];
        rank++;
    }
    
    // 2^(n-rank) - 1
    lll result = 1;
    for (int i = 0; i < n - rank; i++) result *= 2;
    cout << (ll)(result - 1) << endl;
    return 0;
}