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 is , its remainder upon division by is , and its remainder upon division by is .
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.
, so the answer is .
Definition
The Chinese Remainder Theorem (CRT) solves a system of univariate linear congruences of the following form, where are pairwise coprime:
The “Unknown Number of Objects” problem above is an instance of a system of univariate linear congruences.
Procedure
- Compute the product of all moduli ;
- For the -th congruence:
- Compute ;
- Compute modulo and then its inverse ;
- Compute (do not take it modulo ).
- The unique solution of the system modulo is .
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 computed by the algorithm above satisfies, for every , .
When , we have , so . Also, , and therefore:
Thus, for every , the obtained by the algorithm above always satisfies , proving the correctness of the algorithm for solving the system of congruences.
Because we impose no special restrictions on the input , every set of inputs corresponds to a solution . Moreover, if , there is always an such that and are not congruent modulo . Therefore, the coefficient list and the solution 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.
- ;
- Three people walking together, seventy: , so ;
- Five trees with plum blossoms, twenty-one: , so ;
- Seven sons reunited, the middle of the month: , so ;
- Therefore, the unique solution of the system is . (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 satisfies the following system of linear congruences and , where are primes:
We can represent in the following form, called the mixed-radix representation of :
The Garner algorithm computes the coefficients .
Let denote the value for modulo , using the inverse operation:
Substituting into the first equation gives:
Substituting it into the second equation gives:
Subtracting from both sides and dividing by gives
Similarly, we obtain:
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 . 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:
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.
First, when , the answer is clearly .
Otherwise, by Euler's theorem, the answer is
Now consider how to compute
Because is not prime, we cannot guarantee that , every has an inverse, so the expression above cannot be computed directly.
Observe that , and each prime factor occurs only once. We can separately compute modulo the primes , , , and , and finally combine the results with the Chinese Remainder Theorem.
In other words, we need to solve the following system of linear congruences:
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 and .
Convert them into a Diophantine equation: , where are integers. Then .
By Bézout's identity, there is no solution when is not divisible by .
Otherwise, the extended Euclidean algorithm gives a feasible solution pair .
The solution of the original two-congruence system is , where and .
Multiple congruences
Merge them pairwise using the method above.
Exercises
-
Part of this page was translated from the blog post Chinese Remainder Theorem and its English translation Chinese Remainder Theorem. The Russian version is licensed under Public Domain + Leave a Link; the English version is licensed under CC-BY-SA 4.0.