Chinese Remainder Theorem

Introduction

The “Unknown Number of Objects” problem: there is an unknown number of objects; counting them in threes leaves two, counting them in fives leaves three, and counting them in sevens leaves two. What is the number?

That is, find an integer satisfying the following conditions: its remainder upon division by 33 is 22, its remainder upon division by 55 is 33, and its remainder upon division by 77 is 22.

This problem first appeared in The Mathematical Classic of Sun Zi, which also gave a specific method for solving it. In 1247, the Song mathematician Qin Jiushao gave a complete and systematic solution to the “Unknown Number of Objects” problem in volumes 1 and 2, “Dayan Class,” of Shushu Jiuzhang. The mnemonic for the specific problem above was given by the Ming mathematician Cheng Dawei in Suanfa Tongzong:

Three people walking together: seventy; five trees with plum blossoms: twenty-one; seven sons reunited: the middle of the month; subtract one hundred and five to find the answer.

2×70+3×21+2×15=233=2×105+232\times 70+3\times 21+2\times 15=233=2\times 105+23, so the answer is 2323.

Definition

The Chinese Remainder Theorem (CRT) solves a system of univariate linear congruences of the following form, where n1,n2,⋯ ,nkn_1, n_2, \cdots, n_k are pairwise coprime:

{x≡a1(modn1)x≡a2(modn2)⋮x≡ak(modnk)\begin{cases} x &\equiv a_1 \pmod {n_1} \\ x &\equiv a_2 \pmod {n_2} \\ &\vdots \\ x &\equiv a_k \pmod {n_k} \\ \end{cases}

The “Unknown Number of Objects” problem above is an instance of a system of univariate linear congruences.

Procedure

  1. Compute the product of all moduli nn;
  2. For the ii-th congruence:
    1. Compute mi=nnim_i=\frac{n}{n_i};
    2. Compute mim_i modulo nin_i and then its inverse mi−1m_i^{-1};
    3. Compute ci=mimi−1c_i=m_im_i^{-1} (do not take it modulo nin_i).
  3. The unique solution of the system modulo nn is x=∑i=1kaici(modn)x=\sum_{i=1}^k a_ic_i \pmod n.

Implementation

C++

LL CRT(int k, LL* a, LL* r) {
  LL n = 1, ans = 0;
  for (int i = 1; i <= k; i++) n = n * r[i];
  for (int i = 1; i <= k; i++) {
    LL m = n / r[i], b, y;
    exgcd(m, r[i], b, y);  // b * m mod r[i] = 1
    ans = (ans + a[i] * m * b % n) % n;
  }
  return (ans % n + n) % n;
}

Python

def CRT(k, a, r):
    n = 1
    ans = 0
    for i in range(1, k + 1):
        n = n * r[i]
    for i in range(1, k + 1):
        m = n // r[i]
        b = y = 0
        exgcd(m, r[i], b, y)  # b * m mod r[i] = 1
        ans = (ans + a[i] * m * b % n) % n
    return (ans % n + n) % n

Proof

We need to prove that the xx computed by the algorithm above satisfies, for every i=1,2,⋯ ,ki=1,2,\cdots,k, x≡ai(modni)x\equiv a_i \pmod {n_i}.

When i≠ji\neq j, we have mj≡0(modni)m_j \equiv 0 \pmod {n_i}, so cj≡mj≡0(modni)c_j \equiv m_j \equiv 0 \pmod {n_i}. Also, ci≡mi⋅(mi−1 mod ni)≡1(modni)c_i \equiv m_i \cdot (m_i^{-1} \bmod {n_i}) \equiv 1 \pmod {n_i}, and therefore:

x≡∑j=1kajcj(modni)≡aici(modni)≡ai⋅mi⋅(mi−1 mod ni)(modni)≡ai(modni)\begin{aligned} x&\equiv \sum_{j=1}^k a_jc_j &\pmod {n_i} \\ &\equiv a_ic_i &\pmod {n_i} \\ &\equiv a_i \cdot m_i \cdot (m^{-1}_i \bmod n_i) &\pmod {n_i} \\ &\equiv a_i &\pmod {n_i} \end{aligned}

Thus, for every i=1,2,⋯ ,ki=1,2,\cdots,k, the xx obtained by the algorithm above always satisfies x≡ai(modni)x\equiv a_i \pmod{n_i}, proving the correctness of the algorithm for solving the system of congruences.

Because we impose no special restrictions on the input aia_i, every set of inputs {ai}\{a_i\} corresponds to a solution xx. Moreover, if x≠yx\neq y, there is always an ii such that xx and yy are not congruent modulo nin_i. Therefore, the coefficient list {ai}\{a_i\} and the solution xx are in a one-to-one correspondence, and the system always has a unique solution.

Explanation

The following demonstrates how CRT solves the “Unknown Number of Objects” problem.

  1. n=3×5×7=105n=3\times 5\times 7=105;
  2. Three people walking together, seventy: n1=3,m1=n/n1=35,m1−1≡2(mod3)n_1=3, m_1=n/n_1=35, m_1^{-1}\equiv 2\pmod 3, so c1=35×2=70c_1=35\times 2=70;
  3. Five trees with plum blossoms, twenty-one: n2=5,m2=n/n2=21,m2−1≡1(mod5)n_2=5, m_2=n/n_2=21, m_2^{-1}\equiv 1\pmod 5, so c2=21×1=21c_2=21\times 1=21;
  4. Seven sons reunited, the middle of the month: n3=7,m3=n/n3=15,m3−1≡1(mod7)n_3=7, m_3=n/n_3=15, m_3^{-1}\equiv 1\pmod 7, so c3=15×1=15c_3=15\times 1=15;
  5. Therefore, the unique solution of the system is x≡2×70+3×21+2×15≡233≡23(mod105)x\equiv 2\times 70+3\times 21+2\times 15\equiv 233\equiv 23 \pmod {105}. (Subtract one hundred and five to find the answer.)

Garner algorithm

Another use of CRT is to represent a large integer using a set of relatively small primes.

For example, suppose that aa satisfies the following system of linear congruences and a<∏i=1kpia < \prod_{i=1}^k p_i, where pip_i are primes:

{a≡a1(modp1)a≡a2(modp2)⋮a≡ak(modpk)\begin{cases} a &\equiv a_1 \pmod {p_1} \\ a &\equiv a_2 \pmod {p_2} \\ &\vdots \\ a &\equiv a_k \pmod {p_k} \\ \end{cases}

We can represent aa in the following form, called the mixed-radix representation of aa:

a=x1+x2p1+x3p1p2+…+xkp1…pk−1a = x_1 + x_2 p_1 + x_3 p_1 p_2 + \ldots + x_k p_1 \ldots p_{k-1}

The Garner algorithm computes the coefficients x1,…,xkx_1, \ldots, x_k.

Let rijr_{ij} denote the value for pip_i modulo pjp_j, using the inverse operation:

pi⋅ri,j≡1(modpj)p_i \cdot r_{i,j} \equiv 1 \pmod{p_j}

Substituting aa into the first equation gives:

a1≡x1(modp1)a_1 \equiv x_1 \pmod{p_1}

Substituting it into the second equation gives:

a2≡x1+x2p1(modp2)a_2 \equiv x_1 + x_2 p_1 \pmod{p_2}

Subtracting x1x_1 from both sides and dividing by p1p_1 gives

a2−x1≡x2p1(modp2)(a2−x1)r1,2≡x2(modp2)x2≡(a2−x1)r1,2(modp2)\begin{aligned} a_2 - x_1 &\equiv x_2 p_1 &\pmod{p_2} \\ (a_2 - x_1) r_{1,2} &\equiv x_2 &\pmod{p_2} \\ x_2 &\equiv (a_2 - x_1) r_{1,2} &\pmod{p_2} \end{aligned}

Similarly, we obtain:

xk=(…((ak−x1)r1,k−x2)r2,k)−… )rk−1,k mod pkx_k=(\dots((a_k-x_1)r_{1,k}-x_2)r_{2,k})-\dots)r_{k-1,k} \bmod p_k
Implementation

C++

for (int i = 0; i < k; ++i) {
  x[i] = a[i];
  for (int j = 0; j < i; ++j) {
    x[i] = r[j][i] * (x[i] - x[j]);
    x[i] = x[i] % p[i];
    if (x[i] < 0) x[i] += p[i];
  }
}

Python

for i in range(0, k):
    x[i] = a[i]
    for j in range(0, i):
        x[i] = r[j][i] * (x[i] - x[j])
        x[i] = x[i] % p[i]
        if x[i] < 0:
            x[i] = x[i] + p[i]

The time complexity of this algorithm is O(k2)O(k^2). In fact, the Garner algorithm does not require the moduli to be prime; it only requires them to be pairwise coprime. We have the following pseudocode:

Chinese Remainder Algorithm cra⁡(v,m):Input: m=(m0,m1,…,mn−1), mi∈Z+∧gcd⁡(mi,mj)=1 for all i≠j,v=(v0,…,vn−1) where vi=x mod mi.Output: x mod ∏i=0n−1mi.1for i from 1 to (n−1) do2Ci←(∏j=0i−1mj)−1 mod mi3x←v04for i from 1 to (n−1) do5u←(vi−x)⋅Ci mod mi6x←x+u∏j=0i−1mj7return (x)\begin{array}{ll} &\textbf{Chinese Remainder Algorithm }\operatorname{cra}(\mathbf{v}, \mathbf{m})\text{:} \\ &\textbf{Input}\text{: }\mathbf{m}=(m_0,m_1,\dots ,m_{n-1})\text{, }m_i\in\mathbb{Z}^+\land\gcd(m_i,m_j)=1\text{ for all } i\neq j\text{,} \\ &\qquad \mathbf{v}=(v_0,\dots ,v_{n-1}) \text{ where }v_i=x\bmod m_i\text{.} \\ &\textbf{Output}\text{: }x\bmod{\prod_{i=0}^{n-1} m_i}\text{.} \\ 1&\qquad \textbf{for }i\text{ from }1\text{ to }(n-1)\textbf{ do} \\ 2&\qquad \qquad C_i\gets \left(\prod_{j=0}^{i-1}m_j\right)^{-1}\bmod{m_i} \\ 3&\qquad x\gets v_0 \\ 4&\qquad \textbf{for }i\text{ from }1\text{ to }(n-1)\textbf{ do} \\ 5&\qquad \qquad u\gets (v_i-x)\cdot C_i\bmod{m_i} \\ 6&\qquad \qquad x\gets x+u\prod_{j=0}^{i-1}m_j \\ 7&\qquad \textbf{return }(x) \end{array}

It can be seen that the calculation in line 6 corresponds to the mixed-radix representation above.

Applications

For some counting or number-theoretic problems, the given modulus is not prime because the code is to be lengthened, the difficulty increased, or for some other reason!

However, factoring it reveals that it has no repeated prime factors; that is, the modulus is a product of distinct primes.

We can calculate modulo each of these primes separately and finally combine the answers with CRT.

The following problem is a good example.

Luogu P2480 [SDOI2010] Ancient Pig Text

Given G,nG,n(1≤G,n≤1091 \leq G,n \leq 10^9), find:

G∑k∣n(nk) mod 999 911 659G^{\sum_{k\mid n}\binom{n}{k}} \bmod 999~911~659

First, when G=999 911 659G=999~911~659, the answer is clearly 00.

Otherwise, by Euler's theorem, the answer is

G∑k∣n(nk) mod 999 911 658 mod 999 911 659G^{\sum_{k\mid n}\binom{n}{k} \bmod 999~911~658} \bmod 999~911~659

Now consider how to compute

∑k∣n(nk) mod 999 911 658\sum_{k\mid n}\binom{n}{k} \bmod 999~911~658

Because 999 911 658999~911~658 is not prime, we cannot guarantee that ∀x∈[1,999 911 657]\forall x \in [1,999~911~657], every xx has an inverse, so the expression above cannot be computed directly.

Observe that 999 911 658=2×3×4679×35617999~911~658=2 \times 3 \times 4679 \times 35617, and each prime factor occurs only once. We can separately compute ∑k∣n(nk)\sum_{k\mid n}\binom{n}{k} modulo the primes 22, 33, 46794679, and 3561735617, and finally combine the results with the Chinese Remainder Theorem.

In other words, we need to solve the following system of linear congruences:

{x≡a1(mod2)x≡a2(mod3)x≡a3(mod4679)x≡a4(mod35617)\begin{cases} x \equiv a_1 \pmod 2\\ x \equiv a_2 \pmod 3\\ x \equiv a_3 \pmod {4679}\\ x \equiv a_4 \pmod {35617} \end{cases}

To compute a binomial coefficient modulo a small prime, we can use Lucas's theorem.

Extension: non-coprime moduli

Two congruences

Suppose the two congruences are x≡a1(modm1)x\equiv a_1 \pmod {m_1} and x≡a2(modm2)x\equiv a_2 \pmod {m_2}.

Convert them into a Diophantine equation: x=m1p+a1=m2q+a2x=m_1p+a_1=m_2q+a_2, where p,qp, q are integers. Then m1p−m2q=a2−a1m_1p-m_2q=a_2-a_1.

By Bézout's identity, there is no solution when a2−a1a_2-a_1 is not divisible by gcd⁡(m1,m2)\gcd(m_1,m_2).

Otherwise, the extended Euclidean algorithm gives a feasible solution pair (p,q)(p, q).

The solution of the original two-congruence system is x≡b(modM)x\equiv b\pmod M, where b=m1p+a1b=m_1p+a_1 and M=lcm(m1,m2)M=\text{lcm}(m_1, m_2).

Multiple congruences

Merge them pairwise using the method above.

Exercises

This content comes from OI Wiki: Chinese Remainder Theorem. See the original for authors and revision history. AIOJ has adapted the formatting, in-site links, and resource paths.

Content is shared under CC BY-SA 4.0 and SATA license; additional terms are governed by the original notice. Thanks to the OI Wiki authors and contributors; per the SATA terms, please visit the OI Wiki repository and star it to show your support.