No history yet

Chinese Remainder Theorem

Solving Systems of Congruences

So far, we've focused on solving individual modular arithmetic equations. But what happens when a number must satisfy several conditions at once? For example, imagine you're looking for a number xx that leaves a remainder of 2 when divided by 3, a remainder of 3 when divided by 5, and a remainder of 2 when divided by 7.

This scenario can be written as a system of simultaneous congruences:

{x2(mod3)x3(mod5)x2(mod7)\begin{cases} x \equiv 2 \pmod{3} \\ x \equiv 3 \pmod{5} \\ x \equiv 2 \pmod{7} \end{cases}

Finding an xx that works for all three equations requires a more powerful tool. The Chinese Remainder Theorem (CRT) provides a systematic way to solve such systems, provided the moduli meet a specific condition.

The Chinese Remainder Theorem

The Chinese Remainder Theorem states that if you have a system of congruences where the moduli are pairwise coprime, there is a unique solution for xx modulo the product of all the moduli. Pairwise coprime means that for any two moduli in the system, their greatest common divisor is 1.

Given a system of congruences: xa1(modn1)x \equiv a_1 \pmod{n_1} xa2(modn2)x \equiv a_2 \pmod{n_2} ... xak(modnk)x \equiv a_k \pmod{n_k} If n1,n2,...,nkn_1, n_2, ..., n_k are pairwise coprime, there is a unique solution for xx modulo N=n1n2nkN = n_1 \cdot n_2 \cdot \ldots \cdot n_k.

The theorem not only guarantees a solution but also gives us a constructive algorithm to find it.

The Constructive Algorithm

The core idea is to build the solution piece by piece. For each congruence xai(modni)x \equiv a_i \pmod{n_i}, we'll construct a term that satisfies this specific congruence while being equivalent to 0 for all other moduli. Summing these terms gives us the final solution.

Here’s the step-by-step process:

  1. Calculate the total product. First, compute N=n1n2nkN = n_1 \cdot n_2 \cdot \ldots \cdot n_k. This will be the modulus of our final unique solution.

  2. Isolate each congruence. For each congruence ii from 1 to kk, we define Ni=N/niN_i = N / n_i. This value NiN_i is the product of all moduli except nin_i. By its construction, NiN_i is a multiple of every njn_j (where jij \neq i), which means Ni0(modnj)N_i \equiv 0 \pmod{n_j}.

  3. Find the modular inverse. We need to find a number that, when multiplied by NiN_i, is congruent to 1 modulo nin_i. This is the modular multiplicative inverse of NiN_i modulo nin_i. We can find it because we know gcd(Ni,ni)=1\gcd(N_i, n_i) = 1 (since all the moduli are pairwise coprime). Let's call this inverse yiy_i.

yi(Ni)1(modni)y_i \equiv (N_i)^{-1} \pmod{n_i}
  1. Construct the solution. The full solution xx is the sum of terms, where each term corresponds to one of the original congruences. The final sum is taken modulo NN.
xi=1kaiNiyi(modN)x \equiv \sum_{i=1}^{k} a_i N_i y_i \pmod{N}

A Worked Example

Let's solve the system from the beginning:

x2(mod3)x \equiv 2 \pmod{3} x3(mod5)x \equiv 3 \pmod{5} x2(mod7)x \equiv 2 \pmod{7}

The moduli 3, 5, and 7 are all prime, so they are pairwise coprime.

  1. Total product: N=357=105N = 3 \cdot 5 \cdot 7 = 105.

  2. Calculate each NiN_i and its inverse yiy_i:

    • For n1=3n_1=3: N1=105/3=35N_1 = 105 / 3 = 35. We need y1351(mod3)y_1 \equiv 35^{-1} \pmod{3}. Since 352(mod3)35 \equiv 2 \pmod{3}, we need 21(mod3)2^{-1} \pmod{3}, which is 2. So, y1=2y_1 = 2.
    • For n2=5n_2=5: N2=105/5=21N_2 = 105 / 5 = 21. We need y2211(mod5)y_2 \equiv 21^{-1} \pmod{5}. Since 211(mod5)21 \equiv 1 \pmod{5}, we need 11(mod5)1^{-1} \pmod{5}, which is 1. So, y2=1y_2 = 1.
    • For n3=7n_3=7: N3=105/7=15N_3 = 105 / 7 = 15. We need y3151(mod7)y_3 \equiv 15^{-1} \pmod{7}. Since 151(mod7)15 \equiv 1 \pmod{7}, we need 11(mod7)1^{-1} \pmod{7}, which is 1. So, y3=1y_3 = 1.
  3. Construct the solution:

x=a1N1y1+a2N2y2+a3N3y3x = a_1 N_1 y_1 + a_2 N_2 y_2 + a_3 N_3 y_3
x=(2352)+(3211)+(2151)x = (2 \cdot 35 \cdot 2) + (3 \cdot 21 \cdot 1) + (2 \cdot 15 \cdot 1)
x=140+63+30=233x = 140 + 63 + 30 = 233
  1. Find the final result modulo NN: x233(mod105)x \equiv 233 \pmod{105}. 233=2105+23233 = 2 \cdot 105 + 23, so x23(mod105)x \equiv 23 \pmod{105}. The smallest positive integer solution is 23.

Implementation and Application

In competitive programming, the CRT is a powerful technique for problems involving large numbers. If you need to compute a result modulo some large composite number MM, you can sometimes compute it modulo each of the prime power factors of MM and then combine the results using the CRT. This breaks a large, difficult problem into several smaller, more manageable ones.

Here is a C++ implementation. It relies on the Extended Euclidean Algorithm function extendedGcd we developed previously to find modular inverses.

#include <vector>
#include <numeric>

// Assumes a, b are not both zero
long long extendedGcd(long long a, long long b, long long &x, long long &y) {
    if (a == 0) {
        x = 0;
        y = 1;
        return b;
    }
    long long x1, y1;
    long long gcd = extendedGcd(b % a, a, x1, y1);
    x = y1 - (b / a) * x1;
    y = x1;
    return gcd;
}

long long modInverse(long long a, long long m) {
    long long x, y;
    long long g = extendedGcd(a, m, x, y);
    if (g != 1) return -1; // Inverse doesn't exist
    return (x % m + m) % m;
}

// Solves the system x 
// congruences[i].first = a_i
// congruences[i].second = n_i
long long chineseRemainderTheorem(const std::vector<std::pair<long long, long long>>& congruences) {
    long long N = 1;
    for (const auto& cong : congruences) {
        N *= cong.second;
    }

    long long solution = 0;
    for (const auto& cong : congruences) {
        long long a_i = cong.first;
        long long n_i = cong.second;
        long long N_i = N / n_i;
        long long y_i = modInverse(N_i, n_i);

        // Use __int128 to prevent overflow during intermediate multiplication
        __int128 term = (__int128)a_i * N_i * y_i;
        solution = (solution + term) % N;
    }

    return (solution + N) % N;
}

Notice the use of __int128. The intermediate products aiNiyia_i \cdot N_i \cdot y_i can easily exceed the capacity of a long long, even if the final solution fits. Using a 128-bit integer type is a safe way to handle these large intermediate values before taking the final modulo.

Quiz Questions 1/5

What is the fundamental requirement for the moduli (n1,n2,,nkn_1, n_2, \ldots, n_k) in a system of congruences for the Chinese Remainder Theorem to guarantee a unique solution?

Quiz Questions 2/5

In the process of solving a system of congruences using the CRT, if N=n1n2nkN = n_1 \cdot n_2 \cdot \ldots \cdot n_k, what does NiN_i represent?

With the Chinese Remainder Theorem, you can now solve systems of congruences, a technique that opens the door to more advanced number theory problems.