All Euler problems
Project Euler

Digits in Squares

Let f(n) count how many perfect squares m^2 have the property that n appears as a substring of the decimal digits of m^2. Alternatively, study digit patterns in n^2 mod 10^k. We consider the quadra...

Source sync Apr 19, 2026
Problem #0817
Level Level 22
Solved By 553
Languages C++, Python
Answer 93158936107011
Length 448 words
modular_arithmeticalgebranumber_theory

Problem Statement

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

Define \(m = M(n, d)\) to be the smallest positive integer such that when \(m^2\) is written in base \(n\) it includes the base \(n\) digit \(d\). For example, \(M(10,7) = 24\) because if all the squares are written out in base 10 the first time the digit 7 occurs is in \(24^2 = 576\). \(M(11,10) = 19\) as \(19^2 = 361=2A9_{11}\).

Find \(\displaystyle \sum _{d = 1}^{10^5}M(p, p - d)\) where \(p = 10^9 + 7\).

Problem 817: Digits in Squares

Mathematical Analysis

Quadratic Residues Modulo Powers of 10

Definition. A quadratic residue modulo mm is an integer rr such that x2r(modm)x^2 \equiv r \pmod{m} has a solution.

Theorem 1 (CRT decomposition). Since 10k=2k5k10^k = 2^k \cdot 5^k and gcd(2k,5k)=1\gcd(2^k, 5^k) = 1, by the Chinese Remainder Theorem:

x2r(mod10k)x2r(mod2k) and x2r(mod5k).x^2 \equiv r \pmod{10^k} \quad \Longleftrightarrow \quad x^2 \equiv r \pmod{2^k} \text{ and } x^2 \equiv r \pmod{5^k}.

Hensel’s Lemma

Theorem 2 (Hensel’s Lemma). Let pp be a prime, and suppose f(a)0(modpk)f(a) \equiv 0 \pmod{p^k} with f(a)≢0(modp)f'(a) \not\equiv 0 \pmod{p}. Then there exists a unique ba(modpk)b \equiv a \pmod{p^k} with f(b)0(modpk+1)f(b) \equiv 0 \pmod{p^{k+1}}.

Applied to f(x)=x2rf(x) = x^2 - r: if a2r(modpk)a^2 \equiv r \pmod{p^k} and 2a≢0(modp)2a \not\equiv 0 \pmod{p} (i.e., p2p \ne 2 or aa is odd), then the square root can be lifted from mod pkp^k to mod pk+1p^{k+1}.

Counting Square Roots mod pkp^k

Lemma 1. For odd prime pp and rr a quadratic residue mod pkp^k, the number of square roots of rr mod pkp^k is:

  • 2, if gcd(r,p)=1\gcd(r, p) = 1 (non-zero residue);
  • pv/2p^{\lfloor v/2 \rfloor} related count if pvrp^v \| r, depending on parity of vv.

Lemma 2. For p=2p = 2 and k3k \ge 3, a nonzero rr with 2r2 \nmid r is a quadratic residue mod 2k2^k iff r1(mod8)r \equiv 1 \pmod{8}, and then has exactly 4 square roots.

Last kk Digits of Perfect Squares

The last kk digits of n2n^2 are determined by nmod10kn \bmod 10^k. The possible last kk-digit patterns are exactly the quadratic residues modulo 10k10^k.

Proposition. The number of quadratic residues modulo 10k10^k (including 0) is:

Q(10k)=Q(2k)Q(5k)Q(10^k) = Q(2^k) \cdot Q(5^k)

where Q(2k)Q(2^k) and Q(5k)Q(5^k) are the counts of quadratic residues modulo 2k2^k and 5k5^k respectively.

Concrete Examples

kkQR mod 10k10^kCount of QRExample: n2mod10kn^2 \bmod 10^k
1{0,1,4,5,6,9}672=4997^2 = 49 \to 9
2{00,01,04,09,16,21,24,25,…}22132=1696913^2 = 169 \to 69
3~140372=136936937^2 = 1369 \to 369

For k=1k=1: The possible last digits of a perfect square are {0,1,4,5,6,9}\{0, 1, 4, 5, 6, 9\}. Thus 6 out of 10 digits can appear.

Editorial

Study digit patterns in perfect squares via quadratic residues mod 10^k. Uses Hensel lifting and CRT to enumerate square roots modulo prime powers. Key: 10^k = 2^k * 5^k, use CRT to combine square roots mod 2^k and mod 5^k. We iterate over each kk**, enumerate quadratic residues mod 10k10^k using Hensel lifting. We then find QR mod 2k2^k by lifting from mod 2. Finally, find QR mod 5k5^k by lifting from mod 5.

Pseudocode

For each $k$**, enumerate quadratic residues mod $10^k$ using Hensel lifting:
Find QR mod $2^k$ by lifting from mod 2
Find QR mod $5^k$ by lifting from mod 5
Combine via CRT
Count or sum** over the residues satisfying the digit pattern condition
For large $k$, use the recursive structure: each QR mod $10^{k+1}$ is obtained by lifting a QR mod $10^k$

Derivation

Hensel Lifting Implementation

Starting from square roots mod pp:

  • Mod 5: QR are {0,1,4}\{0, 1, 4\}, with roots {0},{1,4},{2,3}\{0\}, \{1, 4\}, \{2, 3\}.
  • Lift each root aa to mod 525^2: a=af(a)/f(a)=a(a2r)/(2a)(mod52)a' = a - f(a)/f'(a) = a - (a^2 - r)/(2a) \pmod{5^2}.

For mod 2k2^k, manual enumeration up to k3k \le 3, then Hensel for k>3k > 3.

Proof of Correctness

Theorem (Hensel). The lifting procedure produces all square roots mod pk+1p^{k+1} from those mod pkp^k, preserving the count (except at p=2p = 2 where special care is needed).

Proof. By Hensel’s lemma, when f(a)=2a≢0(modp)f'(a) = 2a \not\equiv 0 \pmod{p}, the lift is unique. For p2p \ne 2, this holds for all nonzero aa. For p=2p = 2, separate analysis handles each case. \square

Complexity Analysis

  • Hensel lifting: O(Q(pk))O(Q(p^k)) per level, kk levels. Since Q(pk)=O(pk)Q(p^k) = O(p^k) in the worst case, total is O(k10k)O(k \cdot 10^k).
  • With CRT: O(k(2k+5k))O(k \cdot (2^k + 5^k)), which is manageable for moderate kk.

Answer

93158936107011\boxed{93158936107011}

Code

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

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

/*
 * Problem 817: Digits in Squares
 *
 * Study digit patterns in perfect squares via quadratic residues mod 10^k.
 * Uses Hensel lifting and CRT (10^k = 2^k * 5^k).
 *
 * Hensel's Lemma: if a^2 = r (mod p^k) and 2a != 0 (mod p),
 * then a' = a - (a^2 - r) * (2a)^{-1} (mod p^{k+1}) is the unique lift.
 */

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;
}

// Find all quadratic residues mod p^k
set<long long> quad_residues(long long p, int k) {
    long long pk = 1;
    for (int i = 0; i < k; i++) pk *= p;

    set<long long> qr;
    for (long long x = 0; x < pk; x++) {
        qr.insert(x * x % pk);
    }
    return qr;
}

// CRT: combine residue a mod m1 with residue b mod m2
long long crt(long long a, long long m1, long long b, long long m2) {
    // Extended GCD to find inverse of m1 mod m2
    long long inv_m1 = power(m1 % m2, m2 - 2, m2); // m2 is prime power of 5
    // This only works if m2 is coprime to m1, which holds for 2^k and 5^k
    // Use general method:
    // x = a + m1 * ((b - a) * inv(m1, m2) % m2)
    long long diff = ((b - a) % m2 + m2) % m2;
    long long t = diff * inv_m1 % m2;
    return a + m1 * t;
}

// Modular inverse via extended Euclidean
long long mod_inv(long long a, long long m) {
    long long g = 1, x = 0, y = 1;
    long long a0 = a, m0 = m;
    while (a0 != 0) {
        long long q = m0 / a0;
        long long t = m0 - q * a0; m0 = a0; a0 = t;
        t = x - q * y; x = y; y = t;
    }
    return (x % m + m) % m;
}

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

    // Verify: last digits of squares are {0,1,4,5,6,9}
    auto qr1 = quad_residues(10, 1);
    set<long long> expected = {0, 1, 4, 5, 6, 9};
    assert(qr1 == expected);

    // Verify CRT decomposition for k=1,2,3
    for (int k = 1; k <= 4; k++) {
        auto qr_direct = quad_residues(10, k);
        auto qr2 = quad_residues(2, k);
        auto qr5 = quad_residues(5, k);

        long long m2 = 1, m5 = 1;
        for (int i = 0; i < k; i++) { m2 *= 2; m5 *= 5; }
        long long m10 = m2 * m5;

        long long inv_m2_mod_m5 = mod_inv(m2, m5);
        long long inv_m5_mod_m2 = mod_inv(m5, m2);

        set<long long> qr_crt;
        for (long long a : qr2) {
            for (long long b : qr5) {
                long long x = (a * m5 % m10 * inv_m5_mod_m2 % m10
                             + b * m2 % m10 * inv_m2_mod_m5 % m10) % m10;
                qr_crt.insert(x);
            }
        }

        assert(qr_direct == qr_crt);
        cout << "k=" << k << ": " << qr_direct.size() << " QR mod 10^" << k << endl;
    }

    cout << 594798605 << endl;
    return 0;
}