All Euler problems
Project Euler

Chinese Leftovers

Let g(a, n, b, m) denote the smallest non-negative integer x satisfying the simultaneous congruences x equiv a (mod n), x equiv b (mod m), or 0 if no such x exists. Define S = sum_(n=1,000,000)^(1,...

Source sync Apr 19, 2026
Problem #0531
Level Level 13
Solved By 1,382
Languages C++, Python
Answer 4515432351156203105
Length 288 words
number_theorymodular_arithmeticbrute_force

Problem Statement

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

Let \(g(a, n, b, m)\) be the smallest non-negative solution \(x\) to the system: \[\begin {cases} x = a \bmod n \\ x = b \bmod n \end {cases}\] if such a solution exists, otherwise \(0\).

E.g. \(g(2,4,4,6)=10\), but \(g(3,4,4,6)=0\).

Let \(\phi (n)\) be Euler’s totient function.

Let \(f(n,m)=g(\phi (n),n,\phi (m),m)\)

Find \(\sum f(n,m)\) for \(1000000 \le n < m < 1005000\).

Problem 531: Chinese Leftovers

Mathematical Foundation

The Extended Chinese Remainder Theorem

Theorem 1 (Extended CRT). Let n,m1n, m \ge 1 be positive integers and let a,bZa, b \in \mathbb{Z}. The system

xa(modn),xb(modm)x \equiv a \pmod{n}, \quad x \equiv b \pmod{m}

has a solution if and only if gcd(n,m)(ab)\gcd(n, m) \mid (a - b). When a solution exists, it is unique modulo lcm(n,m)\operatorname{lcm}(n, m).

Proof. Set d=gcd(n,m)d = \gcd(n, m).

Necessity. Suppose x0x_0 satisfies both congruences. Then n(x0a)n \mid (x_0 - a) and m(x0b)m \mid (x_0 - b). Since dnd \mid n and dmd \mid m, we have d(x0a)d \mid (x_0 - a) and d(x0b)d \mid (x_0 - b), whence d((x0a)(x0b))=bad \mid \bigl((x_0 - a) - (x_0 - b)\bigr) = b - a. Thus d(ab)d \mid (a - b).

Sufficiency. Assume d(ab)d \mid (a - b). By Bezout’s identity, there exist u,vZu, v \in \mathbb{Z} with un+vm=dun + vm = d. Define

x0=a+nbadu.x_0 = a + n \cdot \frac{b - a}{d} \cdot u.

The fraction (ba)/d(b - a)/d is an integer by hypothesis. Clearly n(x0a)n \mid (x_0 - a), so x0a(modn)x_0 \equiv a \pmod{n}. For the second congruence, observe

x0b=(ab)+nbadu=(ab) ⁣(1nud).x_0 - b = (a - b) + n \cdot \frac{b - a}{d} \cdot u = (a - b)\!\left(1 - \frac{nu}{d}\right).

Since un+vm=dun + vm = d, we have 1nu/d=vm/d1 - nu/d = vm/d, giving

x0b=(ab)vmd.x_0 - b = (a - b) \cdot \frac{vm}{d}.

Now d(ab)d \mid (a - b) by hypothesis, so (ab)/dZ(a - b)/d \in \mathbb{Z}, and thus m(x0b)m \mid (x_0 - b).

Uniqueness. If x0x_0 and x1x_1 both satisfy the system, then n(x1x0)n \mid (x_1 - x_0) and m(x1x0)m \mid (x_1 - x_0). By the characterization of the least common multiple, lcm(n,m)(x1x0)\operatorname{lcm}(n, m) \mid (x_1 - x_0). Hence x0x1(modlcm(n,m))x_0 \equiv x_1 \pmod{\operatorname{lcm}(n, m)}. \blacksquare

Corollary 1. The smallest non-negative solution is x0modlcm(n,m)x_0 \bmod \operatorname{lcm}(n, m), where x0x_0 is the value constructed in the sufficiency proof.

Euler’s Totient Sieve

Lemma 1 (Totient Sieve). Euler’s totient function φ(k)\varphi(k) for all kNk \le N can be computed in O(NloglogN)O(N \log \log N) time and O(N)O(N) space.

Proof. Initialize an array φ[k]=k\varphi[k] = k for 0kN0 \le k \le N. For each prime pNp \le N (identified when φ[p]=p\varphi[p] = p), iterate over all multiples kk of pp and set φ[k]φ[k](11/p)=φ[k]φ[k]/p\varphi[k] \leftarrow \varphi[k] \cdot (1 - 1/p) = \varphi[k] - \varphi[k]/p. By the Euler product formula,

φ(k)=kpk ⁣(11p),\varphi(k) = k \prod_{p \mid k}\!\left(1 - \frac{1}{p}\right),

each factor (11/p)(1 - 1/p) is applied exactly once for each prime pkp \mid k, so the final value of φ[k]\varphi[k] equals φ(k)\varphi(k). The total number of updates is pNN/p=O(NloglogN)\sum_{p \le N} \lfloor N/p \rfloor = O(N \log \log N) by Mertens’ theorem. \blacksquare

Editorial

Compute S = sum of g(phi(n), n, phi(m), m) over 1000000 <= n < m <= 1005000, where g(a,n,b,m) is the smallest non-negative solution to the system x = a (mod n), x = b (mod m), or 0 if none exists. Method: Extended CRT via Bezout’s identity; totient sieve for phi values.

Pseudocode

    N_MAX = 1005000
    phi = TOTIENT_SIEVE(N_MAX)

    S = 0
    For n from 1000000 to 1005000:
        For m from n+1 to 1005000:
            a = phi[n], b = phi[m]
            d = gcd(n, m)
            If (a - b) mod d != 0 then
                continue
            (g, u, v) = EXTENDED_GCD(n, m)
            L = n / d * m
            x = (a + n * ((b - a) / d) * u) mod L
            if x < 0: x += L
            S += x
    Return S

Complexity Analysis

  • Totient sieve: O(NloglogN)O(N \log \log N) time, O(N)O(N) space, with N=1005000N = 1\,005\,000.
  • Double loop: (50012)1.25×107\binom{5001}{2} \approx 1.25 \times 10^7 pairs, each requiring O(logN)O(\log N) for the extended Euclidean algorithm. Total: O(K2logN)O(K^2 \log N) where K=5001K = 5001.
  • Overall: O(NloglogN+K2logN)O(N \log \log N + K^2 \log N) time, O(N)O(N) space.

Answer

4515432351156203105\boxed{4515432351156203105}

Code

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

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

typedef long long ll;
typedef __int128 lll;

/*
 * Problem 531: Chinese Leftovers
 *
 * Compute S = sum of g(phi(n), n, phi(m), m) over 1000000 <= n < m <= 1005000.
 * g(a,n,b,m) = smallest non-negative x with x=a(mod n), x=b(mod m), or 0.
 *
 * Method: Euler totient sieve + extended CRT via Bezout's identity.
 * Time: O(N log log N + K^2 log N).
 */

ll extended_gcd(ll a, ll b, ll &x, ll &y) {
    if (a == 0) { x = 0; y = 1; return b; }
    ll x1, y1;
    ll g = extended_gcd(b % a, a, x1, y1);
    x = y1 - (b / a) * x1;
    y = x1;
    return g;
}

ll crt(ll a, ll n, ll b, ll m) {
    ll u, v;
    ll g = extended_gcd(n, m, u, v);
    if ((a - b) % g != 0) return 0;
    ll mg = m / g;
    ll diff = ((lll)(b - a) / g % mg * u % mg + mg) % mg;
    ll lcm = n / g * m;
    ll x = (lll)a + (lll)n * diff;
    x = ((x % lcm) + lcm) % lcm;
    return x;
}

int main() {
    const int LO = 1000000, HI = 1005000;
    vector<ll> phi(HI + 1);
    iota(phi.begin(), phi.end(), 0);
    for (int i = 2; i <= HI; i++) {
        if (phi[i] == i) {
            for (int j = i; j <= HI; j += i)
                phi[j] -= phi[j] / i;
        }
    }

    ll S = 0;
    for (int n = LO; n <= HI; n++)
        for (int m = n + 1; m <= HI; m++)
            S += crt(phi[n], n, phi[m], m);

    cout << S << endl;
    return 0;
}