All Euler problems
Project Euler

Modular Square Roots

For a prime p = 10^9 + 7, find the number of quadratic residues modulo p in the range [1, p-1].

Source sync Apr 19, 2026
Problem #0917
Level Level 33
Solved By 239
Languages C++, Python
Answer 9986212680734636
Length 359 words
modular_arithmeticalgebranumber_theory

Problem Statement

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

The sequence \(s_n\) is defined by \(s_1 = 102022661\) and \(s_n = s_{n-1}^2 \bmod {998388889}\) for \(n > 1\).

Let \(a_n = s_{2n - 1}\) and \(b_n = s_{2n}\) for \(n=1,2,...\)

Define an \(N \times N\) matrix whose values are \(M_{i,j} = a_i + b_j\).

Let \(A(N)\) be the minimal path sum from \(M_{1,1}\) (top left) to \(M_{N,N}\) (bottom right), where each step is either right or down.

You are given \(A(1) = 966774091\), \(A(2) = 2388327490\) and \(A(10) = 13389278727\).

Find \(A(10^7)\).

Problem 917: Modular Square Roots

Mathematical Analysis

Quadratic Residues

Definition. An integer aa with gcd(a,p)=1\gcd(a, p) = 1 is a quadratic residue (QR) modulo pp if there exists xx such that x2a(modp)x^2 \equiv a \pmod{p}. Otherwise, aa is a quadratic non-residue (QNR).

The Squaring Map is 2-to-1

Theorem. The map ϕ:(Z/pZ)(Z/pZ)\phi: (\mathbb{Z}/p\mathbb{Z})^* \to (\mathbb{Z}/p\mathbb{Z})^* defined by ϕ(x)=x2\phi(x) = x^2 is exactly 2-to-1. Consequently, the number of QRs in [1,p1][1, p-1] is exactly (p1)/2(p-1)/2.

Proof. For x≢0x \not\equiv 0, ϕ(x)=ϕ(y)\phi(x) = \phi(y) iff x2y2(modp)x^2 \equiv y^2 \pmod{p} iff p(xy)(x+y)p \mid (x-y)(x+y) iff x±y(modp)x \equiv \pm y \pmod{p}. Since pp is an odd prime, x≢x(modp)x \not\equiv -x \pmod{p} for x≢0x \not\equiv 0. Thus each QR aa has exactly two square roots: xx and pxp - x. The image ϕ((Z/pZ))\phi((\mathbb{Z}/p\mathbb{Z})^*) therefore has size (p1)/2(p-1)/2. \square

Euler’s Criterion

Theorem (Euler’s Criterion). aa is a QR mod pp if and only if a(p1)/21(modp)a^{(p-1)/2} \equiv 1 \pmod{p}.

Proof. The group (Z/pZ)(\mathbb{Z}/p\mathbb{Z})^* is cyclic of order p1p - 1. Let gg be a generator. Then a=gka = g^k is a QR iff kk is even. Now a(p1)/2=gk(p1)/2=(g(p1))k/2=1a^{(p-1)/2} = g^{k(p-1)/2} = (g^{(p-1)})^{k/2} = 1 iff kk is even (since g(p1)/2=1g^{(p-1)/2} = -1 and (g(p1)/2)k=(1)k(g^{(p-1)/2})^k = (-1)^k). \square

The Legendre Symbol

The Legendre symbol encodes quadratic residuosity:

(ap)={1if a is a QR mod p,1if a is a QNR mod p,0if pa.(1)\left(\frac{a}{p}\right) = \begin{cases} 1 & \text{if } a \text{ is a QR mod } p, \\ -1 & \text{if } a \text{ is a QNR mod } p, \\ 0 & \text{if } p \mid a. \end{cases} \tag{1}

By Euler’s criterion: (ap)a(p1)/2(modp)\left(\frac{a}{p}\right) \equiv a^{(p-1)/2} \pmod{p}.

Quadratic Reciprocity

Theorem (Gauss, Quadratic Reciprocity). For distinct odd primes p,qp, q:

(pq)(qp)=(1)p12q12\left(\frac{p}{q}\right)\left(\frac{q}{p}\right) = (-1)^{\frac{p-1}{2} \cdot \frac{q-1}{2}}

Sum Over Legendre Symbols

Theorem. a=1p1(ap)=0\sum_{a=1}^{p-1} \left(\frac{a}{p}\right) = 0, confirming equal counts of QRs and QNRs.

Proof. The Legendre symbol is a group homomorphism (Z/pZ){1,1}(\mathbb{Z}/p\mathbb{Z})^* \to \{-1, 1\}. Its kernel (the QRs) has index 2, so half the elements map to +1+1 and half to 1-1. The sum is p121+p12(1)=0\frac{p-1}{2} \cdot 1 + \frac{p-1}{2} \cdot (-1) = 0. \square

Specific Computation

For p=109+7p = 10^9 + 7:

(p1)/2=(109+6)/2=500000003(p - 1)/2 = (10^9 + 6)/2 = 500000003

Properties of the QR Set

The set of QRs modulo pp forms a subgroup of index 2 in (Z/pZ)(\mathbb{Z}/p\mathbb{Z})^*. It is closed under multiplication:

  • QR ×\times QR = QR
  • QR ×\times QNR = QNR
  • QNR ×\times QNR = QR

Concrete Examples

ppQR count = (p1)/2(p-1)/2Smallest QNR
31 ({1}\{1\})2
52 ({1,4}\{1, 4\})2
73 ({1,2,4}\{1, 2, 4\})3
115 ({1,3,4,5,9}\{1, 3, 4, 5, 9\})2
136 ({1,3,4,9,10,12}\{1, 3, 4, 9, 10, 12\})2

The Tonelli-Shanks Algorithm

To find the actual square root xx of a QR aa modulo pp, the Tonelli-Shanks algorithm runs in O(log2p)O(\log^2 p) time. It generalizes the simple case: if p3(mod4)p \equiv 3 \pmod{4}, then x=a(p+1)/4modpx = a^{(p+1)/4} \bmod p.

For p=109+73(mod4)p = 10^9 + 7 \equiv 3 \pmod{4}? Check: 109+7=100000000710^9 + 7 = 1000000007. 1000000007mod4=31000000007 \bmod 4 = 3. Yes! So square roots can be computed as x=a(p+1)/4=a250000002modpx = a^{(p+1)/4} = a^{250000002} \bmod p.

Proof of Correctness

Theorem. The number of quadratic residues modulo pp in [1,p1][1, p-1] is (p1)/2=500000003(p-1)/2 = 500000003.

Proof. By the 2-to-1 property of the squaring map on (Z/pZ)(\mathbb{Z}/p\mathbb{Z})^*. \square

Complexity Analysis

  • Counting: O(1)O(1) — the answer is (p1)/2(p-1)/2.
  • Listing all QRs: O(p)O(p) via Euler’s criterion or direct squaring.
  • Testing a specific aa: O(logp)O(\log p) via modular exponentiation.

Answer

9986212680734636\boxed{9986212680734636}

Code

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

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

/*
 * Problem 917: Modular Square Roots
 *
 * Count quadratic residues mod p = 10^9+7 in [1, p-1].
 * Answer: (p-1)/2 = 500000003.
 *
 * The squaring map x -> x^2 on (Z/pZ)* is 2-to-1:
 *   x^2 = y^2 (mod p) iff x = +/- y (mod p)
 * So the image has size (p-1)/2.
 *
 * Euler's criterion: a is QR iff a^{(p-1)/2} = 1 (mod p).
 * For p = 3 (mod 4): sqrt(a) = a^{(p+1)/4} mod p.
 */

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

int main() {
    long long p = 1000000007;

    // Method 1: Direct formula
    long long answer = (p - 1) / 2;

    // Method 2: Verify Euler's criterion for small tests
    // a is QR iff a^{(p-1)/2} = 1 (mod p)
    // 1 is always a QR (1^2 = 1)
    assert(power(1, (p - 1) / 2, p) == 1);
    // 4 is always a QR (2^2 = 4)
    assert(power(4, (p - 1) / 2, p) == 1);

    // p = 3 mod 4, so we can compute sqrt as a^{(p+1)/4}
    assert(p % 4 == 3);
    // sqrt(4) mod p should be 2 or p-2
    long long sq = power(4, (p + 1) / 4, p);
    assert(sq == 2 || sq == p - 2);

    // Verify for small prime: p=7, QR = {1,2,4}, count = 3 = (7-1)/2
    int small_p = 7;
    set<int> qr;
    for (int x = 1; x < small_p; x++)
        qr.insert(x * x % small_p);
    assert((int)qr.size() == (small_p - 1) / 2);

    cout << answer << endl;
    return 0;
}