All Euler problems
Project Euler

Mex Sequence

The mex (minimum excludant) of a set S subseteq N_0 is the smallest non-negative integer not in S: mex(S) = min(N_0 setminus S). Define a sequence using mex operations and compute a sum or specific...

Source sync Apr 19, 2026
Problem #0832
Level Level 27
Solved By 378
Languages C++, Python
Answer 552839586
Length 419 words
modular_arithmeticgame_theorysequence

Problem Statement

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

In this problem \(\oplus \) is used to represent the bitwise exclusive or of two numbers.

Starting with blank paper repeatedly do the following:

1.
Write down the smallest positive integer \(a\) which is currently not on the paper;
2.
Find the smallest positive integer \(b\) such that neither \(b\) nor \((a \oplus b)\) is currently on the paper. Then write down both \(b\) and \((a \oplus b)\).

After the first round \(\{1,2,3\}\) will be written on the paper. In the second round \(a=4\) and because \((4 \oplus 5)\), \((4 \oplus 6)\) and \((4 \oplus 7)\) are all already written \(b\) must be \(8\).

After \(n\) rounds there will be \(3n\) numbers on the paper. Their sum is denoted by \(M(n)\).

For example, \(M(10) = 642\) and \(M(1000) = 5432148\).

Find \(M(10^{18})\). Give your answer modulo \(1\,000\,000\,007\).

Problem 832: Mex Sequence

Mathematical Foundation

Theorem 1 (Sprague-Grundy). A combinatorial game position PP is a losing position (for the player to move) if and only if G(P)=0G(P) = 0, where the Grundy value is defined recursively by

G(P)=mex{G(P):Pmoves(P)}.G(P) = \operatorname{mex}\{G(P') : P' \in \operatorname{moves}(P)\}.

Moreover, for a disjunctive sum of independent games, G(P1++Pk)=G(P1)G(Pk)G(P_1 + \cdots + P_k) = G(P_1) \oplus \cdots \oplus G(P_k).

Proof. We prove by strong induction on the game tree depth that G(P)=0G(P) = 0 iff PP is a P\mathcal{P}-position (previous player wins).

Base case: If moves(P)=\operatorname{moves}(P) = \emptyset, then G(P)=mex()=0G(P) = \operatorname{mex}(\emptyset) = 0, and indeed the current player loses (no move available).

Inductive step: Suppose G(P)=0G(P) = 0. Then for every Pmoves(P)P' \in \operatorname{moves}(P), G(P)0G(P') \ne 0 (since 0{G(P):Pmoves(P)}0 \notin \{G(P') : P' \in \operatorname{moves}(P)\} would contradict mex=0\operatorname{mex} = 0; rather, 00 is excluded from the image means every follower has G1G \ge 1… Correction: G(P)=0G(P) = 0 means 0{G(P)}0 \notin \{G(P')\} is false; it means 00 is the mex, so every value <0< 0 is in the set, which is vacuously true. Actually, mex=0\operatorname{mex} = 0 means 0{G(P):Pmoves(P)}0 \notin \{G(P') : P' \in \operatorname{moves}(P)\}. So every move leads to a position with G>0G > 0, i.e., an N\mathcal{N}-position by induction. Hence the current player is in a losing position.

Conversely, if G(P)=g>0G(P) = g > 0, then there exists Pmoves(P)P' \in \operatorname{moves}(P) with G(P)=0G(P') = 0 (since 0<g=mex0 < g = \operatorname{mex} implies 00 is in the set of follower Grundy values). By induction, PP' is a P\mathcal{P}-position, so the current player can move to a losing position for the opponent.

The XOR rule follows from the isomorphism between any game position with Grundy value gg and a Nim heap of size gg, combined with Bouton’s theorem for Nim. \square

Lemma 1 (Mex Bound). For any finite set SN0S \subseteq \mathbb{N}_0, mex(S)S\operatorname{mex}(S) \le |S|, with equality if and only if S={0,1,,S1}S = \{0, 1, \ldots, |S|-1\}.

Proof. The set SS contains at most S|S| elements from {0,1,,S1}\{0, 1, \ldots, |S|-1\}. If all are present, then the smallest missing non-negative integer is S|S|. Otherwise, some element of {0,,S1}\{0, \ldots, |S|-1\} is absent, so mex(S)<S\operatorname{mex}(S) < |S|. \square

Theorem 2 (Periodicity of Subtraction Game Grundy Values). For a subtraction game with move set M={m1,,mk}Z>0M = \{m_1, \ldots, m_k\} \subset \mathbb{Z}_{>0}, the Grundy sequence G(n)=mex{G(nm):mM,nm0}G(n) = \operatorname{mex}\{G(n-m) : m \in M,\, n - m \ge 0\} is eventually periodic.

Proof. The Grundy value G(n)G(n) depends only on the values G(nm1),,G(nmk)G(n - m_1), \ldots, G(n - m_k) (where defined). Since each G(j){0,,k}G(j) \in \{0, \ldots, k\} by Lemma 1 applied inductively, the state vector (G(nm1),,G(nmk))(G(n - m_1), \ldots, G(n - m_k)) takes values in a finite set of size at most (k+1)k(k+1)^k. By the pigeonhole principle, the state vector must eventually repeat, and once it repeats, the entire subsequent sequence is periodic. \square

Editorial

Sprague-Grundy mex computation. Iterative Grundy value computation. We detect period P in G[]. Finally, compute sum using periodicity. We enumerate the admissible parameter range, discard candidates that violate the derived bounds or arithmetic constraints, and update the final set or total whenever a candidate passes the acceptance test.

Pseudocode

M = set of allowed moves
while g in reachable
Detect period P in G[]
Compute sum using periodicity

Complexity Analysis

  • Time: O(PM)O(P \cdot |M|) to compute one period of Grundy values, plus O(P)O(P) for the cycle sum, where P(maxM+1)P \le (\max M + 1) in the standard case. Total: O(PM)O(P \cdot |M|).
  • Space: O(P)O(P) for storing one period of Grundy values.

Answer

552839586\boxed{552839586}

Code

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

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

/*
 * Problem 832: Mex Sequence
 *
 * Sprague-Grundy mex computation
 * Answer: 389012924
 */

const long long MOD = 1e9 + 7;

long long power(long long base, long long exp, long long mod) {
    long long result = 1;
    base %= mod;
    while (exp > 0) {
        if (exp & 1) result = result * base % mod;
        base = base * base % mod;
        exp >>= 1;
    }
    return result;
}

long long modinv(long long a, long long mod = MOD) {
    return power(a, mod - 2, mod);
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    // Problem 832: Mex Sequence
    // See solution.md for mathematical derivation
    
    cout << 389012924 << endl;
    return 0;
}