## 10.4 Solving Modular Linear Equations
![](https://box.kancloud.cn/485bc67a7beadb016ac9d44f235f6e03_27x27.jpg) Next we discuss solving the modular equation
![](https://box.kancloud.cn/b8feebe8fdde212ffd8cb2c2379dab0c_363x23.jpg)
for *x*, where *x* is an equivalence class modulo *n*, and *m, n* > 0. We will apply this result in [Section 10.7](LiB0088.html#1212) when we develop the RSA cryptosystem.
Let <\[*m*\]*n*> be the subgroup generated by \[*m*\]*n* relative to the group (*Zn* +). Since <\[*m*\]*n*> = {\[0\]*n*, \[*m*\]*n*, \[2*m*\]*n*, …}, [Equation 10.12](#ch10eqn12) has a solution if and only if
![](https://box.kancloud.cn/8edacdbe8577ea5b40542e71befc06e5_110x23.jpg)
Example 10.45**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**Consider the group (**Z**8, +). Since
**![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**
![](https://box.kancloud.cn/16665a45d96e6ed894851008fa69b2c9_231x24.jpg)
the equation
![](https://box.kancloud.cn/1f7d02dd6c413b46511318f0189f7ca0_92x23.jpg)
has a solution if and only if \[*k*\]8 is \[0\]8, \[6\]8, \[4\]8, or \[2\]8. For example, solutions to
![](https://box.kancloud.cn/b0a889d2810de2b08425b12ea7813b79_92x23.jpg)
are *x* = \[2\]8 and *x* = \[6\]8.
The following theorem tells us precisely the elements of the set 〈\[*m*\]*n*〉.
Theorem 10.23**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**Consider the group (**Z***n*, +). For any \[*m*\]*n* ∊ **Z***n*, we have that
**![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**
![](https://box.kancloud.cn/ac18bcc542ca36488ec67a0e97068f89_400x23.jpg)
where *d* = gcd(*n, m*). This means
![](https://box.kancloud.cn/64553c6352183d6557679452e0e8ff13_206x37.jpg)
Proof: First show 〈\[*d*\]*n*〉 ⊆ 〈\[*m*\]*n*〉. Owing to [Theorem 10.2](LiB0081.html#1005), there exists integers *i* and *j* such that
![](https://box.kancloud.cn/b4bbe7cc3218269d90557693a6413e14_104x21.jpg)
Owing to the previous equality, for any integer *k*,
![](https://box.kancloud.cn/84f95923014e6546ca2ebe75195cc158_132x20.jpg)
which means \[*kd*\]*n* = \[*kim*\]*n*, and therefore \[*kd*\]*n* ∊ 〈\[*m*\]*n*〉, We conclude that 〈\[d\]n〉 ⊆.
Next show 〈\[m\]n〉 ⊆ 〈\[d\]n〉. Since *d*|*m*, there is an integer *i* such that *m* = *id.* Therefore, for any integer *k*,
![](https://box.kancloud.cn/9b09790d3f1e2108d9c752e3948fef6b_123x23.jpg)
which means 〈\[km\]n〉 ∊ 〈\[d\]n〉 . We conclude 〈\[m\]n〉 ⊆ 〈\[d\]n〉.
The final result follows from the results just established and [Theorem 10.20](LiB0083.html#1094).
Corollary 10.6**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**The equation
**![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**
![](https://box.kancloud.cn/8febe65b20faf105b5e997a90d4522a8_111x23.jpg)
has a solution if and only if *d*/*k*, where *d* = gcd(*n, m*).
Furthermore, if the equation has a solution, it has *d* solutions.
Proof: As mentioned at the beginning of this section, the equation has a solution if and only if
![](https://box.kancloud.cn/4a1e90c1840d8cd11455c7f5cbacf284_112x23.jpg)
Since [Theorem 10.23](#ch10ex77) implies
![](https://box.kancloud.cn/101aed2b61bcbd876187a75e9d8510c2_400x23.jpg)
this means the equation has a solution if and only *d*’*k*’ for some *k*’ ∊ \[*k*\]*n.* Since \[*k*\]*n* is an equivalence class modulo *n* and *d*|*n*, clearly *d*|*k*’ for one *k*’ ∊ \[*k*\]*n* if and only if it does so for all members of \[*kn.* This proves the first part of the corollary.
As to the second part, according to [Theorem 10.23](#ch10ex77), *ord*<\[*m*\]*n*) = *n*/*d.* Therefore, owing to [Corollary 10.4](LiB0083.html#1100), the sequence
![](https://box.kancloud.cn/8c5dc78d4b5892cd8069da70019d0bce_165x23.jpg)
has period *n*/*d* and the first *n*/*d* items are distinct. This means, if \[k\]*n* ∊ <\[*m*\]*n*>, that \[*k*\]*n* appears exactly *d* times in the set
![](https://box.kancloud.cn/254c8fae917655f2c7d71e38d15815f8_296x24.jpg)
Clearly, each of these appearances is owing to a different member of **Z***n.* This completes the proof.
Corollary 10.7**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**The equation
**![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**
![](https://box.kancloud.cn/44f39901034ea56a3999a13b87572e3d_104x23.jpg)
has a solution for every equivalence class \[*k*\]*n* if and only if gcd(*n, m*) = 1. Furthermore, if this is the case, each \[*k*\]*n* has a unique solution.
Proof: The proof follows immediately from [Corollary 10.6](#ch10ex78).
Corollary 10.8**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**The equivalence class \[*m*\]*n* has a multiplicative inverse modulo *n* if and only if gcd(*n, m*) = 1. That is, the equation
**![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**
![](https://box.kancloud.cn/3e04dc36778718c1471a3baecd3b8225_110x23.jpg)
has a solution if and only if gcd(*n, m*) = 1. Furthermore, if it has an inverse, that inverse is unique.
Proof: The proof follows immediately from [Corollary 10.6](#ch10ex78). The uniqueness actually also follows from [Theorem 10.16](LiB0083.html#1078).
Example 10.46**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**Consider the group (**Z**8, +). Since gcd(8, 6) = 2, according to [Theorem 10.23](#ch10ex77),
**![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**
![](https://box.kancloud.cn/e080e2a0c13625f86bdab4fdefb413ee_231x24.jpg)
which agrees with our result in [Example 10.45](#ch10ex76). Owing to [Corollary 10.6](#ch10ex78), the equation
![](https://box.kancloud.cn/d4b19f7e08271fa5100fd5c16db4b118_102x23.jpg)
has exactly two solutions when \[*k*\]8 is any member of 〈\[6\]8〉. In [Example 10.45](#ch10ex76), we noted the two solutions when \[*k*\]8 = \[4\]8 are *x* = \[2\]8 and *x* = \[6\]8.
Example 10.47**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**Consider again the group (**Z**8, +). Since gcd(8, 5) = 1, according to [Theorem 10.23](#ch10ex77),
**![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**
![](https://box.kancloud.cn/ff309e83a27b4f19aa92b409d2e76ef2_382x23.jpg)
According to [Corollary 10.7](#ch10ex79), the equation
![](https://box.kancloud.cn/97f7bae14354c3a143395cc716dc3f96_92x23.jpg)
has exactly one solution when \[*k*\]8 is any member of 〈\[5\]8〉. For example, when \[*k*\]8 = \[3\]8, the solution is *x* = \[7\]8.
Example 10.48**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**Consider **Z**9. Since gcd(9, 6) = 3, [Corollary 10.8](#ch10ex80) implies \[6\]9 does not have a multiplicative inverse modulo 9. Since gcd(9, 5) = 1, [Corollary 10.8](#ch10ex80) implies \[5\]9 does have a multiplicative inverse modulo 9. That inverse is \[2\]9.
**![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**
Theorem 10.24**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**Let *d* = gcd(*n, m*) and let *i* and *j* be integers such that
**![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**
![](https://box.kancloud.cn/0063b842bc495e810073b6afb468ea3d_359x21.jpg)
(We know from [Theorem 10.2](LiB0081.html#1005) that such *i* and *j* exist.) Suppose further *d*|*k.* Then the equation
![](https://box.kancloud.cn/bed7ffd1ae4728517e83925c9fa395f0_111x23.jpg)
has solution
![](https://box.kancloud.cn/7167120c005d11720665ac4f674d315a_88x48.jpg)
Proof: Owing to Equality 10.13, we have
![](https://box.kancloud.cn/09e6f6207044384e94e170be5826134a_106x24.jpg)
Since ![](https://box.kancloud.cn/d8c9c7885e037926ef2edae1dab3a50c_15x26.jpg) is an integer, we can multiply both sides of this equality by ![](https://box.kancloud.cn/f902e6a2b3ed56137dbd0f0827bc5670_42x28.jpg) yielding
![](https://box.kancloud.cn/858db384350c1deff738e5dd29e383b9_150x48.jpg)
which means
![](https://box.kancloud.cn/0c2612bc473a479daffe6e61ae6a1a01_152x48.jpg)
This proves the theorem.
Example 10.49**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**Consider the equation
**![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**
![](https://box.kancloud.cn/3f4f878ae8a13c0885bb0e0acc48bdf9_100x24.jpg)
We have gcd(8, 6) = 2,
![](https://box.kancloud.cn/456e0997403989885a0c1010caf09315_140x21.jpg)
and 2|4. Therefore, the previous theorem implies the equation
![](https://box.kancloud.cn/65047078e166985e318aed501084bb05_91x23.jpg)
has solution
![](https://box.kancloud.cn/0a0e76957d0a79e41997f1734ef8083b_240x48.jpg)
Theorem 10.25**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**Suppose the equation
**![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**
![](https://box.kancloud.cn/00168700ad27dabe531dedb602059252_103x23.jpg)
is solvable, *x* = \[*j*\]*n* is one solution, and *d* = gcd(*n, m*). Then the *d* distinct solutions of this equation are
![](https://box.kancloud.cn/9640829460304555acb7a45462ae38e3_400x43.jpg)
Proof: Owing to [Corollary 10.6](#ch10ex78), there are exactly *d* solutions. Clearly,
![](https://box.kancloud.cn/679141eb8226c609a5400ac64dfc4335_302x42.jpg)
So the *d* modulo classes in Expression 10.14 are all distinct. We complete the theorem by showing each of these classes is a solution to the equation. Since \[*j*\]*n* is a solution of \[*m*\]*n* *x* = \[*k*\]*n*,
![](https://box.kancloud.cn/896e0b834dc450d9d260ef2bc5399eab_107x23.jpg)
Therefore, for *l* = 0, 1, …, *d* – 1,
![](https://box.kancloud.cn/a07bdab6c4aa57633c63d41ebb06fdb5_400x44.jpg)
which means ![](https://box.kancloud.cn/48f5d80bdeef038fc3c00910d1c3c38a_71x26.jpg) is also a solution to the equation.
Example 10.50**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**In [Example 10.49](#ch10ex85), we showed that one solution of
**![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**
![](https://box.kancloud.cn/33394d27ed09d6f17fe42a97e491cf56_98x23.jpg)
is \[6\]8. Since gcd(8, 6) = 2, the previous theorem implies the other solution is
![](https://box.kancloud.cn/9729471b8e3d1945cf76f7a6846120d1_215x48.jpg)
[Corollary 10.6](#ch10ex78), [Theorem 10.24](#ch10ex84), and [Theorem 10.25](#ch10ex86) enable us to write a simple algorithm for solving modular linear equations. That is, we first employ [Corollary 10.6](#ch10ex78) to see if a solution exists. If one does, we then use [Theorem 10.24](#ch10ex84) to find one solution and [Theorem 10.25](#ch10ex86) to find the other solutions. The algorithm follows:
Algorithm 10.3 Solve Modular Linear Equation**![Start example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**Problem: Find all solutions to a modular linear equation
**![End example](https://box.kancloud.cn/e95df9d604ab2d89febe370ae4d88fb1_1x1.gif)**
Inputs: positive integers *m* and *n*, and integer *k.*
Outputs: if the equation \[*m*\]*n* *x* = \[*k*\]*n* is solvable, all solutions to it.
```
void solve_linear (int n, int m, int k)
{
index l;
int i, j, d;
Euclid (n, m, d, i, j); // Call Algorithm 10.2.
if (d|k)
for (l = 0; l <= d - 1; l++)
cout
}
```
The input size in [Algorithm 10.3](#ch10ex88) is the number of bits it takes to encode the input, which is given by
![](https://box.kancloud.cn/5acce3f2b8f6a9c159dcc4760d9b30b6_400x22.jpg)
The time complexity includes the time complexity of [Algorithm 10.2](LiB0082.html#1043) (Euclid's [Algorithm 2](LiB0015.html#146)), which we already know is *O*(*st*), plus the time complexity of the **for**-*l* loop. Since *d* can be as large as *m* or *n*, this time complexity is worst-case exponential in terms of the input size. However, we can do nothing about this since the problem requires that we compute and display an exponential number of values in the worst case.
- Table of Contents
- BackCover
- Foundations of Algorithms Using C++ Pseudocode, Third Edition
- Preface
- Chapter Contents
- Pedagogy
- Course Outlines
- Acknowledgments
- Errors
- Chapter 1: Algorithms - Efficiency, Analysis, and Order
- 1.2 The Importance of Developing Efficient Algorithms
- 1.3 Analysis of Algorithms
- 1.4 Order
- 1.5 Outline of This Book
- Exercises
- Chapter 2: Divide-and-Conquer
- 2.1 Binary Search
- 2.2 Mergesort
- 2.3 The Divide-and-Conquer Approach
- 2.4 Quicksort (Partition Exchange Sort)
- 2.5 Strassen's Matrix Multiplication Algorithm
- 2.6 Arithmetic with Large Integers
- 2.7 Determining Thresholds
- 2.8 When Not to Use Divide-and-Conquer
- Exercises
- Chapter 3: Dynamic Programming
- 3.1 The Binomial Coefficient
- 3.2 Floyd's Algorithm for Shortest Paths
- 3.3 Dynamic Programming and Optimization Problems
- 3.4 Chained Matrix Multiplication
- 3.5 Optimal Binary Search Trees
- 3.6 The Traveling Salesperson Problem
- Exercises
- Chapter 4: The Greedy Approach
- 4.1 Minimum Spanning Trees
- 4.2 Dijkstra's Algorithm for Single-Source Shortest Paths
- 4.3 Scheduling
- 4.4 Huffman Code
- 4.5 The Greedy Approach versus Dynamic Programming: The Knapsack Problem
- Exercises
- Chapter 5: Backtracking
- 5.2 The n-Queens Problem
- 5.3 Using a Monte Carlo Algorithm to Estimate the Efficiency of a Backtracking Algorithm
- 5.4 The Sum-of-Subsets Problem
- 5.5 Graph Coloring
- 5.6 The Hamiltonian Circuits Problem
- 5.7 The 0-1 Knapsack Problem
- Exercises
- Chapter 6: Branch-and-Bound
- 6.1 Illustrating Branch-and-Bound with the 0 - 1 Knapsack problem
- 6.2 The Traveling Salesperson Problem
- 6.3 Abductive Inference (Diagnosis)
- Exercises
- Chapter 7: Introduction to Computational Complexity - The Sorting Problem
- 7.2 Insertion Sort and Selection Sort
- 7.3 Lower Bounds for Algorithms that Remove at Most One Inversion per Comparison
- 7.4 Mergesort Revisited
- 7.5 Quicksort Revisited
- 7.6 Heapsort
- 7.6.1 Heaps and Basic Heap Routines
- 7.6.2 An Implementation of Heapsort
- 7.7 Comparison of Mergesort, Quicksort, and Heapsort
- 7.8 Lower Bounds for Sorting Only by Comparison of Keys
- 7.8.1 Decision Trees for Sorting Algorithms
- 7.8.2 Lower Bounds for Worst-Case Behavior
- 7.8.3 Lower Bounds for Average-Case Behavior
- 7.9 Sorting by Distribution (Radix Sort)
- Exercises
- Chapter 8: More Computational Complexity - The Searching Problem
- 8.1 Lower Bounds for Searching Only by Comparisons of Keys
- 8.2 Interpolation Search
- 8.3 Searching in Trees
- 8.4 Hashing
- 8.5 The Selection Problem: Introduction to Adversary Arguments
- Exercises
- Chapter 9: Computational Complexity and Interactability - An Introduction to the Theory of NP
- 9.2 Input Size Revisited
- 9.3 The Three General Problem Categories
- 9.4 The Theory of NP
- 9.5 Handling NP-Hard Problems
- Exercises
- Chapter 10: Number-Theoretic Algorithms
- 10.1 Number Theory Review
- 10.2 Computing the Greatest Common Divisor
- 10.3 Modular Arithmetic Review
- 10.4 Solving Modular Linear Equations
- 10.5 Computing Modular Powers
- 10.6 Finding Large Prime Numbers
- 10.7 The RSA Public-Key Cryptosystem
- Exercises
- Chapter 11: Introduction to Parallel Algorithms
- 11.1 Parallel Architectures
- 11.2 The PRAM Model
- Exercises
- Appendix A: Review of Necessary Mathematics
- A.2 Functions
- A.3 Mathematical Induction
- A.4 Theorems and Lemmas
- A.5 Logarithms
- A.6 Sets
- A.7 Permutations and Combinations
- A.8 Probability
- Exercises
- Appendix B: Solving Recurrence Equations - With Applications to Analysis of Recursive Algorithms
- B.2 Solving Recurrences Using the Characteristic Equation
- B.3 Solving Recurrences by Substitution
- B.4 Extending Results for n, a Power of a Positive Constant b, to n in General
- B.5 Proofs of Theorems
- Exercises
- Appendix C: Data Structures for Disjoint Sets
- References
- Index
- Index_B
- Index_C
- Index_D
- Index_E
- Index_F
- Index_G
- Index_H
- Index_I
- Index_J
- Index_K
- Index_L
- Index_M
- Index_N
- Index_O
- Index_P
- Index_Q
- Index_R
- Index_S
- Index_T
- Index_U
- Index_V
- Index_W-X
- Index_Y
- Index_Z
- List of Figures
- List of Tables
- List of Algorithms, Examples, and Theorems
- List of Sidebars