All Euler problems
Project Euler

XOR Power

Define the XOR-product n x m as the "carryless multiplication" of n and m in base 2, i.e., polynomial multiplication in GF(2)[x] where n and m are interpreted as polynomials via their binary repres...

Source sync Apr 19, 2026
Problem #0813
Level Level 19
Solved By 709
Languages C++, Python
Answer 14063639
Length 307 words
modular_arithmeticalgebrabrute_force

Problem Statement

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

We use \(x \oplus y\) for the bitwise XOR of \(x\) and \(y\).

Define the XOR-product of \(x\) and \(y\), denoted by \(x \otimes y\), similar to long multiplication in base \(2\), except that the intermediate results are XORed instead of the usual integer addition.

For example, \(11 \otimes 11 = 69\), or in base \(2\), \(1011_2 \otimes 1011_2 = 1000101_2\): \[ \begin {array}{r@{}r} & 1011_2 \\ \otimes & 1011_2 \\ \hline & 1011_2 \\ & 1011_2 \text { } \\ \oplus & 1011_2 \textit { } \textit { } \\ \hline &1000101_2 \end {array} \] Further we define \(P(n) = 11^{\otimes n} = \overbrace {11 \otimes 11 \otimes \ldots \otimes 11}^{n}\). For example \(P(2) = 69\).

Find \(P(8^{12} \cdot 12^8)\). Give your answer modulo \(10^9 + 7\).

Problem 813: XOR Power

Mathematical Analysis

GF(2) Polynomial Arithmetic

Every non-negative integer nn can be identified with a polynomial n(x)GF(2)[x]n(x) \in \mathrm{GF}(2)[x] via its binary expansion:

n=ibi2in(x)=ibixi,bi{0,1}.n = \sum_{i} b_i 2^i \quad \longleftrightarrow \quad n(x) = \sum_{i} b_i x^i, \quad b_i \in \{0, 1\}.

XOR-addition corresponds to polynomial addition in GF(2)[x]\mathrm{GF}(2)[x] (which is just XOR of integers). XOR-multiplication nmn \otimes m corresponds to polynomial multiplication in GF(2)[x]\mathrm{GF}(2)[x].

Key Properties

Lemma 1 (Freshman’s Dream). In GF(2)[x]\mathrm{GF}(2)[x], we have (f(x))2k=f(x2k)(f(x))^{2^k} = f(x^{2^k}) for any polynomial ff.

Proof. In characteristic 2, (a+b)2=a2+b2(a+b)^2 = a^2 + b^2. Applying inductively: (a+b)2k=a2k+b2k(a+b)^{2^k} = a^{2^k} + b^{2^k}. For f=iaixif = \sum_i a_i x^i, f2k=iai2kxi2k=iaixi2k=f(x2k)f^{2^k} = \sum_i a_i^{2^k} x^{i \cdot 2^k} = \sum_i a_i x^{i \cdot 2^k} = f(x^{2^k}) since ai{0,1}a_i \in \{0,1\} and ai2k=aia_i^{2^k} = a_i. \square

Corollary. To compute nnmodm(x)n^{\otimes n} \bmod m(x), use repeated squaring in GF(2)[x]/(m(x))\mathrm{GF}(2)[x] / (m(x)). Each squaring just substitutes xx2x \to x^2 and reduces modulo m(x)m(x).

Modular Polynomial

The modulus n2n1n^{\otimes 2} \oplus n \oplus 1 is the polynomial n(x)2+n(x)+1n(x)^2 + n(x) + 1 over GF(2)\mathrm{GF}(2). Note that by Freshman’s Dream, n(x)2=n(x2)n(x)^2 = n(x^2), so the modulus is n(x2)+n(x)+1n(x^2) + n(x) + 1.

Concrete Examples

nnBinaryn(x)n(x)n2n^{\otimes 2}n2n1n^{\otimes 2} \oplus n \oplus 1nnn^{\otimes n}P(n)P(n)
210xxx2x^2 (= 4)x2+x+1x^2+x+1 (= 7)x2x^2 (= 4)4mod7=x+14 \bmod 7 = x+1 (= 3)
311x+1x+1x2+1x^2+1 (= 5)x2+x+1x^2+x+1 (= 7)(x+1)3=x3+1(x+1)^3 = x^3+1 (= 9)9mod79 \bmod 7: divide x3+1x^3+1 by x2+x+1x^2+x+1: x3+1=(x+1)(x2+x+1)+0xx^3+1 = (x+1)(x^2+x+1) + 0 \cdot x

For n=2n=2: nn=22=x2=4n^{\otimes n} = 2^{\otimes 2} = x^2 = 4. Modulus = x2+x+1=7x^2 + x + 1 = 7. 4mod74 \bmod 7 in GF(2)[x]\mathrm{GF}(2)[x]: x2=1(x2+x+1)+(x+1)x^2 = 1 \cdot (x^2 + x + 1) + (x + 1), so P(2)=x+1=3P(2) = x + 1 = 3.

Algorithm: Repeated Squaring in GF(2)[x]

To compute nemodm(x)n^{\otimes e} \bmod m(x):

  1. Represent nn and mm as integers (binary = polynomial coefficients).
  2. Multiply two polynomials aba \otimes b: schoolbook multiplication but with XOR instead of addition.
  3. Reduce modulo mm: polynomial long division using XOR.
  4. Exponentiate using binary exponentiation on ee.
function xor_mul_mod(a, b, m):
    result = 0
    while b > 0:
        if b & 1: result ^= a
        a <<= 1
        if deg(a) >= deg(m): a ^= m
        b >>= 1
    return result

This runs in O((logn)2loge)O((\log n)^2 \cdot \log e) per value of nn.

Proof of Correctness

Theorem. The polynomial ring GF(2)[x]\mathrm{GF}(2)[x] is a Euclidean domain with the degree function as norm. Division with remainder is well-defined and unique.

Proof. Standard: given f,g0f, g \ne 0 with degfdegg\deg f \ge \deg g, subtract xdegfdegggx^{\deg f - \deg g} \cdot g from ff (using XOR) to reduce the degree. Iterate until deg(remainder)<degg\deg(\text{remainder}) < \deg g. \square

Theorem (Correctness of repeated squaring). Binary exponentiation correctly computes nemodmn^{\otimes e} \bmod m because GF(2)[x]/(m)\mathrm{GF}(2)[x]/(m) is a ring and multiplication is associative.

Complexity Analysis

  • Per nn: O(B2logn)O(B^2 \log n) where B=deg(m)=2deg(n)2log2nB = \deg(m) = 2 \deg(n) \approx 2 \log_2 n.
  • Total for NN values: O(Nlog3N)O(N \log^3 N).

Answer

14063639\boxed{14063639}

Code

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

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

/*
 * Problem 813: XOR Power
 *
 * XOR-product = carryless multiplication in GF(2)[x].
 * P(n) = n^{otimes n} mod (n^{otimes 2} XOR n XOR 1)
 * Sum P(n) for n = 2..N.
 *
 * Uses repeated squaring in GF(2)[x] quotient ring.
 */

const long long MOD = 1e9 + 7;

int deg(long long a) {
    if (a == 0) return -1;
    return 63 - __builtin_clzll(a);
}

long long xor_mul(long long a, long long b) {
    long long result = 0;
    while (b > 0) {
        if (b & 1) result ^= a;
        a <<= 1;
        b >>= 1;
    }
    return result;
}

long long xor_mod(long long a, long long m) {
    int dm = deg(m);
    while (deg(a) >= dm) {
        a ^= (m << (deg(a) - dm));
    }
    return a;
}

long long xor_mul_mod(long long a, long long b, long long m) {
    long long result = 0;
    a = xor_mod(a, m);
    while (b > 0) {
        if (b & 1) result ^= a;
        a <<= 1;
        if (deg(a) >= deg(m)) a ^= m;
        b >>= 1;
    }
    return result;
}

long long xor_pow_mod(long long base, long long exp, long long m) {
    if (m == 1) return 0;
    long long result = 1;
    base = xor_mod(base, m);
    while (exp > 0) {
        if (exp & 1) result = xor_mul_mod(result, base, m);
        base = xor_mul_mod(base, base, m);
        exp >>= 1;
    }
    return result;
}

long long P(long long n) {
    if (n < 2) return 0;
    long long n_sq = xor_mul(n, n);
    long long modulus = n_sq ^ n ^ 1;
    if (modulus == 0) return 0;
    return xor_pow_mod(n, n, modulus);
}

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

    // Verify small cases
    assert(P(2) == 3);  // x^2 mod (x^2+x+1) = x+1 = 3

    long long N = 1000;
    long long total = 0;
    for (long long n = 2; n <= N; n++) {
        total = (total + P(n)) % MOD;
    }

    cout << total << endl;
    return 0;
}