All Euler problems
Project Euler

250250

Find the number of non-empty subsets of {1^1, 2^2, 3^3,..., 250250^250250} whose element sum is divisible by 250. Give the answer modulo 10^16.

Source sync Apr 19, 2026
Problem #0250
Level Level 08
Solved By 3,466
Languages C++, Python
Answer 1425480602091519
Length 312 words
dynamic_programmingmodular_arithmeticnumber_theory

Problem Statement

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

Find the number of non-empty subsets of \(\{1^1, 2^2, 3^3,\dots , 250250^{250250}\}\), the sum of whose elements is divisible by \(250\). Enter the rightmost \(16\) digits as your answer.

Problem 250: 250250

Mathematical Foundation

Theorem 1 (Residue reduction). For divisibility of a sum by 250250, only the residues ri=iimod250r_i = i^i \bmod 250 matter. That is, a subset T{1,,250250}T \subseteq \{1, \ldots, 250250\} has iTii0(mod250)\sum_{i \in T} i^i \equiv 0 \pmod{250} if and only if iTri0(mod250)\sum_{i \in T} r_i \equiv 0 \pmod{250}.

Proof. For any integers aia_i, ai(aimodm)(modm)\sum a_i \equiv \sum (a_i \bmod m) \pmod{m}. Apply with m=250m = 250 and ai=iia_i = i^i. \square

Theorem 2 (DP on residue classes). Let dp[j]dp[j] denote the number of subsets (including the empty set) of {11,,NN}\{1^1, \ldots, N^N\} whose element sum is congruent to j(mod250)j \pmod{250}, reduced modulo M=1016M = 10^{16}. The recurrence

dp[j]=dp[j]+dp[(jri)mod250]dp'[j] = dp[j] + dp[(j - r_i) \bmod 250]

processed for i=1,2,,Ni = 1, 2, \ldots, N correctly computes dp[j]dp[j] for all 0j<2500 \le j < 250.

Proof. Induction on the number of elements processed. Initially, dp[0]=1dp[0] = 1 (empty set), dp[j]=0dp[j] = 0 for j0j \ne 0.

For element ii with residue rir_i: every subset of {1,,i}\{1, \ldots, i\} either excludes ii (counted by old dp[j]dp[j]) or includes ii (counted by old dp[(jri)mod250]dp[(j - r_i) \bmod 250], since including ii adds rir_i to the residue). We must update all 250 entries simultaneously (using a temporary copy or in-place with a fresh array) to avoid double-counting.

By induction, after processing all NN elements, dp[j]dp[j] equals (mod MM) the number of subsets with sum j(mod250)\equiv j \pmod{250}. \square

Lemma 1 (Periodicity of residues). The sequence ri=iimod250r_i = i^i \bmod 250 has period dividing 500500.

Proof. By CRT, 250=2×125250 = 2 \times 125. We show periodicity modulo each factor:

  • Mod 2: iimod2i^i \bmod 2 depends only on imod2i \bmod 2, period 2.
  • Mod 125: Write i=125q+ri = 125q + r. For gcd(i,125)=1\gcd(i, 125) = 1, iimod125i^i \bmod 125 depends on imod125i \bmod 125 (for the base) and imodφ(125)=imod100i \bmod \varphi(125) = i \bmod 100 (for the exponent). Since lcm(125,100)=500\text{lcm}(125, 100) = 500, the period divides 500. For 5i5 \mid i, similar analysis via lifting-the-exponent gives the same bound.
  • Combined: lcm(2,500)=500\text{lcm}(2, 500) = 500. \square

Theorem 3 (Final answer). The number of non-empty subsets with sum divisible by 250 is

answer=(dp[0]1)mod1016\text{answer} = (dp[0] - 1) \bmod 10^{16}

where dp[0]dp[0] counts all subsets (including empty) with sum 0\equiv 0.

Proof. dp[0]dp[0] includes the empty subset, which has sum 0. Subtracting 1 excludes it. \square

Editorial

.., 250250^250250} with sum divisible by 250. DP on residue classes mod 250. Answer mod 10^16. Key: Only need i^i mod 250 for each element. DP array of size 250. We use fast modular exponentiation. We then dP on residue classes. Finally, subtract empty subset.

Pseudocode

Compute residues r_i = i^i mod 250
Use fast modular exponentiation
DP on residue classes
Subtract empty subset

Complexity Analysis

  • Time: O(N×250)=O(250250×250)6.25×107O(N \times 250) = O(250250 \times 250) \approx 6.25 \times 10^7 modular additions. Computing rir_i takes O(NlogN)O(N \log N) via modular exponentiation (O(logi)O(\log i) per element). Total: O(N250)O(N \cdot 250) dominates.
  • Space: O(250)O(250) for the DP array.

Answer

1425480602091519\boxed{1425480602091519}

Code

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

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

int main() {
    const long long MOD = 10000000000000000LL; // 10^16
    const int N = 250250;
    const int M = 250;

    vector<long long> dp(M, 0);
    dp[0] = 1;

    for (int i = 1; i <= N; i++) {
        // Compute i^i mod 250
        long long base = i % M;
        long long exp = i;
        long long r = 1;
        long long b = base;
        long long e = exp;
        while (e > 0) {
            if (e & 1) r = (r * b) % M;
            b = (b * b) % M;
            e >>= 1;
        }
        int ri = (int)r;

        // Update dp
        vector<long long> ndp(M);
        for (int j = 0; j < M; j++) {
            ndp[j] = (dp[j] + dp[((j - ri) % M + M) % M]) % MOD;
        }
        dp = ndp;
    }

    // Answer: dp[0] - 1 (exclude empty subset)
    long long answer = (dp[0] - 1 + MOD) % MOD;
    cout << answer << endl;
    return 0;
}