扩展欧几里得算法用于解决二元一次不定方程、一次同余方程、逆元等问题
二元一次不定方程
- 二元一次不定方程的定义: a x + b y = c , ( a , b , c ∈ Z 且 a , b ≠ 0 ) (1) ax + by = c,(a, b, c \in Z且a, b \neq 0) \tag{1} ax+by=c,(a,b,c∈Z且a,b=0)(1)
- 如果 c = 0 c = 0 c=0,则方程的整数解为: x = − b t , y = a t , ( t ∈ Z ) x = -bt,y = at,(t \in Z) x=−bt,y=at,(t∈Z)
- 如果 c c c为负数,则(1)式两边乘以 − 1 -1 −1,等号右边就变成正整数;因为所求的 x x x, y y y可正可负,所以我们只用讨论 a a a, b b b是正整数的情况。
- 设 d d d为 a a a和 b b b的最大公因数,即 d = g c d ( a , b ) , a = a 1 ∗ d , b = b 1 ∗ d , ( a 1 , b 1 ) = 1 d = gcd(a, b),a = a_1 * d,b = b_1 * d,(a_1, b_1) = 1 d=gcd(a,b),a=a1∗d,b=b1∗d,(a1,b1)=1,则(1)式变为 d ∗ ( a 1 x + b 1 x ) = c (2) d * (a_1x + b_1x) = c \tag{2} d∗(a1x+b1x)=c(2)
结论:当 d ∤ c d\nmid c d∤c 时,(1)式没有整数解;当 d ∣ c d\mid c d∣c 时,(1)式一定有整数解,这可以通过贝祖定理(又称裴蜀定理)得到。
贝祖定理:如果 a a a和 b b b是整数,且 g c d ( a , b ) = d gcd(a, b) = d gcd(a,b)=d,那么对于任意的整数 x , y , a x + b y x,y,ax + by x,y,ax+by都一定是 d d d的倍数;特别的,一定存在整数 x , y x,y x,y,使 a x + b y = d ax + by = d ax+by=d成立。
- 贝祖定理的一个重要推论是: a a a和 b b b互质的充分必要条件是存在整数 x , y x,y x,y,使 a x + b y = 1 ax + by = 1 ax+by=1
- a x + b y ax + by ax+by能够得到的最小结果就是它们的最小公倍数
我们通过几个例子,解释 x x x和 y y y的求解步骤,并在此基础上得出扩展欧几里得算法。
例1: 17 x + 5 y = 1 17x + 5y = 1 17x+5y=1
∵ g c d ( 17 , 5 ) = 1 , ∴ 方 程 有 解 \because gcd(17, 5) = 1,\therefore 方程有解 ∵gcd(17,5)=1,∴方程有解
(
3
∗
5
+
2
)
x
+
5
y
=
1
(3*5 + 2)x + 5y = 1
(3∗5+2)x+5y=1,整理得:
5
(
3
x
+
y
)
+
2
x
=
1
5(3x + y) + 2x = 1
5(3x+y)+2x=1
用换元法,如果我们求出如下方程的解,
5
x
′
+
2
y
′
=
1
5x^{'} + 2y^{'} = 1
5x′+2y′=1,则:
x
=
y
′
,
y
=
x
′
−
3
y
′
x = y^{'},y = x^{'} - 3y^{'}
x=y′,y=x′−3y′
(
2
∗
2
+
1
)
x
′
+
2
y
′
=
1
(2*2 + 1)x^{'} + 2y^{'} = 1
(2∗2+1)x′+2y′=1,整理得:
2
(
2
x
′
+
y
′
)
+
x
′
=
1
2(2x^{'} + y^{'}) + x^{'} = 1
2(2x′+y′)+x′=1
用换元法,如果我们求出如下方程的解,
2
x
′
′
+
y
′
′
=
1
2x^{''} + y^{''} = 1
2x′′+y′′=1,则:
x
′
=
y
′
′
,
y
′
=
x
′
′
−
2
y
′
′
x^{'} = y^{''},y^{'} = x^{''} - 2y^{''}
x′=y′′,y′=x′′−2y′′
(
2
∗
1
+
0
)
x
′
′
+
y
′
′
=
1
(2*1 + 0)x^{''} + y^{''} = 1
(2∗1+0)x′′+y′′=1,整理得:
1
(
2
x
′
′
+
y
′
′
)
+
0
x
′
′
=
1
1(2x^{''} + y^{''}) + 0x^{''} = 1
1(2x′′+y′′)+0x′′=1
用换元法,如果我们求出如下方程的解,
1
x
′
′
′
+
0
y
′
′
′
=
1
1x^{'''} + 0y^{'''} = 1
1x′′′+0y′′′=1,则:
x
′
′
=
y
′
′
′
,
y
′
′
=
x
′
′
′
−
2
y
′
′
′
x^{''} = y^{'''},y^{''} = x^{'''} - 2y^{'''}
x′′=y′′′,y′′=x′′′−2y′′′
显而易见,方程
1
x
′
′
′
+
0
y
′
′
′
=
1
1x^{'''} + 0y^{'''} = 1
1x′′′+0y′′′=1 有解
x
′
′
′
=
1
,
y
′
′
′
=
0
x^{'''} = 1,y^{'''} = 0
x′′′=1,y′′′=0。
x
′
′
′
x^{'''}
x′′′的系数
1
1
1,就是原方程中
17
17
17和
5
5
5的最大公约数
回溯可得,
x
′
′
=
0
,
y
′
′
=
1
x^{''} = 0,y^{''} = 1
x′′=0,y′′=1
x
′
=
1
,
y
′
=
−
2
x^{'} = 1,y^{'} = -2
x′=1,y′=−2
x
=
−
2
,
y
=
7
x = -2,y = 7
x=−2,y=7
例2: 27 x + 21 y = 3 27x + 21y = 3 27x+21y=3
∵ g c d ( 27 , 21 ) = 3 , ∴ 方 程 有 解 \because gcd(27, 21) = 3,\therefore 方程有解 ∵gcd(27,21)=3,∴方程有解
(
1
∗
21
+
6
)
x
+
21
y
=
3
(1*21 + 6)x + 21y = 3
(1∗21+6)x+21y=3,整理得:
21
(
x
+
y
)
+
6
x
=
3
21(x + y) + 6x = 3
21(x+y)+6x=3
用换元法,如果我们求出如下方程的解,
21
x
′
+
6
y
′
=
3
21x^{'} + 6y^{'} = 3
21x′+6y′=3,则:
x
=
y
′
,
y
=
x
′
−
y
′
x = y^{'},y = x^{'} - y^{'}
x=y′,y=x′−y′
(
3
∗
6
+
3
)
x
′
+
6
y
′
=
3
(3*6 + 3)x^{'} + 6y^{'} = 3
(3∗6+3)x′+6y′=3,整理得:
6
(
3
x
′
+
y
′
)
+
3
x
′
=
3
6(3x^{'} + y^{'}) + 3x^{'} = 3
6(3x′+y′)+3x′=3
用换元法,如果我们求出如下方程的解,
6
x
′
′
+
3
y
′
′
=
3
6x^{''} + 3y^{''} = 3
6x′′+3y′′=3,则:
x
′
=
y
′
′
,
y
′
=
x
′
′
−
3
y
′
′
x^{'} = y^{''},y^{'} = x^{''} - 3y^{''}
x′=y′′,y′=x′′−3y′′
(
2
∗
3
+
0
)
x
′
′
+
3
y
′
′
=
3
(2*3 + 0)x^{''} + 3y^{''} = 3
(2∗3+0)x′′+3y′′=3,整理得:
3
(
2
x
′
′
+
y
′
′
)
+
0
x
′
′
=
3
3(2x^{''} + y^{''}) + 0x^{''} = 3
3(2x′′+y′′)+0x′′=3
用换元法,如果我们求出如下方程的解,
3
x
′
′
′
+
0
y
′
′
′
=
3
3x^{'''} + 0y^{'''} = 3
3x′′′+0y′′′=3,则:
x
′
′
=
y
′
′
′
,
y
′
′
=
x
′
′
′
−
2
y
′
′
′
x^{''} = y^{'''},y^{''} = x^{'''} - 2y^{'''}
x′′=y′′′,y′′=x′′′−2y′′′
显而易见,方程
3
x
′
′
′
+
0
y
′
′
′
=
3
3x^{'''} + 0y^{'''} = 3
3x′′′+0y′′′=3 有解
x
′
′
′
=
1
,
y
′
′
′
=
0
x^{'''} = 1,y^{'''} = 0
x′′′=1,y′′′=0。
x
′
′
′
x^{'''}
x′′′的系数
3
3
3,就是原方程中
27
27
27和
21
21
21的最大公约数
回溯可得,
x
′
′
=
0
,
y
′
′
=
1
x^{''} = 0,y^{''} = 1
x′′=0,y′′=1
x
′
=
1
,
y
′
=
−
3
x^{'} = 1,y^{'} = -3
x′=1,y′=−3
x
=
−
3
,
y
=
4
x = -3,y = 4
x=−3,y=4
对于方程: a x + b y = g c d ( a , b ) ax + by = gcd(a, b) ax+by=gcd(a,b)
(
⌊
a
/
b
⌋
∗
b
+
a
%
b
)
x
+
b
y
=
g
c
d
(
a
,
b
)
(\lfloor a/b \rfloor * b + a \% b)x + by = gcd(a, b)
(⌊a/b⌋∗b+a%b)x+by=gcd(a,b),整理得:
b
(
⌊
a
/
b
⌋
∗
x
+
y
)
+
a
%
b
∗
x
=
g
c
d
(
a
,
b
)
b(\lfloor a/b \rfloor * x + y) + a \% b * x = gcd(a, b)
b(⌊a/b⌋∗x+y)+a%b∗x=gcd(a,b)
用换元法,如果我们求出如下方程的解,
b
∗
x
′
+
a
%
b
∗
y
′
=
g
c
d
(
a
,
b
)
b * x^{'} + a \% b * y^{'} = gcd(a, b)
b∗x′+a%b∗y′=gcd(a,b),则:
x
=
y
′
,
y
=
x
′
−
⌊
a
/
b
⌋
∗
y
′
x = y^{'},y = x^{'} - \lfloor a/b \rfloor * y^{'}
x=y′,y=x′−⌊a/b⌋∗y′
不断递归,最后我们得到方程:
g
c
d
(
a
,
b
)
∗
x
~
+
0
∗
y
~
=
g
c
d
(
a
,
b
)
gcd(a, b) * \tilde x + 0 * \tilde y = gcd(a, b)
gcd(a,b)∗x~+0∗y~=gcd(a,b),
可得该方程的一组解:
x
~
=
1
,
y
~
=
0
\tilde x = 1,\tilde y = 0
x~=1,y~=0。
x
~
\tilde x
x~的系数,就是原方程中
a
a
a和
b
b
b的最大公约数
不断回溯,最后得到原方程的解
扩展欧几里得算法的参考代码:
//二元一次不定方程:ax + by = gcd(a, b)
//函数返回 gcd(a, b);通过引用传递,返回一组解 (x, y)
int exgcd(int a, int b, int &x, int &y) {
if (b == 0) {
x = 1, y = 0;
return a;
}
int gcd = exgcd(b, a % b, x, y);
int t = x;
x = y;
y = t - a / b * y;
return gcd;
}
总结:
对于一般情况, a x + b y = c ax + by = c ax+by=c,( a , b , c a, b, c a,b,c为正整数),设 d = g c d ( a , b ) d = gcd(a, b) d=gcd(a,b)
- 如果 d ∤ c d \nmid c d∤c,方程无解
- 如果
d
∣
c
d \mid c
d∣c,
- 先求出方程 a x + b y = d ax + by = d ax+by=d的一组解 x 0 , y 0 x_0, y_0 x0,y0
- 原方程的一组解为 x ′ = x 0 ∗ c / d , y ′ = y 0 ∗ c / d x^{'} = x_0 * c/d,y^{'} = y_0 * c/d x′=x0∗c/d,y′=y0∗c/d
- 原方程的通解为 x = x ′ + k ∗ b / d , y = y ′ − k ∗ a / d x = x^{'} + k * b / d,y = y^{'} - k * a / d x=x′+k∗b/d,y=y′−k∗a/d, k k k为任意整数
- 设 p = b / d p = b / d p=b/d, x x x的最小非负整数解为 ( x ′ % p + p ) % p (x^{'} \% \ p + p) \ \% \ p (x′% p+p) % p
- 设 q = a / d q = a / d q=a/d, y y y的最小非负整数解为 ( y ′ % q + q ) % q (y^{'} \% \ q + q) \ \% \ q (y′% q+q) % q
- 如果 a a a或 b b b是负数,则函数返回的最大公约数可能为负数,将 p p p取绝对值,才能用以上方法得到 x x x的最小非负整数解
求解一次同余方程 a x ≡ b ( m o d m ) ax \equiv b \ (mod \ m) ax≡b (mod m)
- 一次同余方程亦称线性同余方程,指未知数仅出现一次幂的同余方程。
- 该同余方程等价于 a x = m ∗ ( − y ) + b ax = m * (-y) + b ax=m∗(−y)+b,即 a x + m y = b ax + my = b ax+my=b
- 如果 g c d ( a , m ) ∤ b gcd(a, m) \nmid b gcd(a,m)∤b,该方程无解
- 如果 g c d ( a , m ) ∣ b gcd(a, m) \mid b gcd(a,m)∣b,用上述方法求解
求解乘法逆元
- 对于正整数 a , m a, m a,m,如果有 a x ≡ 1 ( m o d m ) ax \equiv 1 \ (mod \ m) ax≡1 (mod m),则称 x x x的最小正整数解为 a a a模 m m m的逆元,也叫做数论倒数,记作 a − 1 a^{-1} a−1。 a a a和 x x x一定都和 m m m互质,如果 a a a和 m m m不互质就不存在逆元。
- 乘法运算中 a ∗ a − 1 = 1 a * a^{-1} = 1 a∗a−1=1,模运算中, a ∗ a − 1 ≡ 1 ( m o d m ) a * a^{-1} \equiv 1 \ (mod \ m) a∗a−1≡1 (mod m)
扩展欧几里得算法求逆元:
- 见求解一次同余方程
费马小定理求逆元:
- 如果模数 m m m为质数,可利用费马小定理求逆元: a m − 1 ≡ 1 ( m o d m ) a^{m-1} \equiv 1 \ (mod \ m) am−1≡1 (mod m)
- 因为 a ∗ a m − 2 ≡ 1 ( m o d m ) a * a^{m-2} \equiv 1 \ (mod \ m) a∗am−2≡1 (mod m),所以 a a a的逆元是 a m − 2 % m a^{m-2} \ \% m am−2 %m,用快速幂计算
- 例如, m m m为7时, 3 ∗ 3 5 ≡ 1 ( m o d 7 ) 3 * 3^5 \equiv 1 \ (mod \ 7) 3∗35≡1 (mod 7), 3 5 % 7 3^5 \ \% \ 7 35 % 7为 3 3 3模 7 7 7的逆元
欧拉函数求逆元:
- 欧拉定理:如果 a a a和 m m m互质,设 ϕ ( m ) \phi(m) ϕ(m)为小于 m m m且与 m m m互质的正整数的个数,则有 a ϕ ( m ) ≡ 1 ( m o d m ) a^{\phi(m)} \equiv 1 \ (mod \ m) aϕ(m)≡1 (mod m)
- 因为 a ∗ a ϕ ( m ) − 1 ≡ 1 ( m o d m ) a * a ^ {\phi(m) - 1} \equiv 1 \ (mod \ m) a∗aϕ(m)−1≡1 (mod m),所以 a a a的逆元是 a ϕ ( m ) − 1 % m a^{\phi(m)-1} \ \% m aϕ(m)−1 %m,用快速幂计算
- m m m可以不是质数
- 例如, m m m为8时, ϕ ( 8 ) = 4 \phi(8) = 4 ϕ(8)=4, 3 ∗ 3 3 ≡ 1 ( m o d 8 ) 3 * 3^3 \equiv 1 \ (mod \ 8) 3∗33≡1 (mod 8), 3 3 % 8 3^3 \ \% \ 8 33 % 8为 3 3 3模 8 8 8的逆元
逆元的用处:
- 取余运算有如下性质
- ( a + b ) % m = ( a % m + b % m ) % m (a + b) \% m = (a \% m + b \% m) \%m (a+b)%m=(a%m+b%m)%m
- ( a − b ) % m = ( a % m − b % m ) % m (a - b) \% m = (a \% m - b \% m) \%m (a−b)%m=(a%m−b%m)%m
- ( a ∗ b ) % m = ( a % m ∗ b % m ) % m (a * b) \% m = (a \% m * b \% m) \%m (a∗b)%m=(a%m∗b%m)%m
- a b % m = ( a % m ) b % m a^b \ \% m = (a \% m)^b \ \%m ab %m=(a%m)b %m
- 但对除法不成立
- ( a / b ) % m ≠ ( a % m / b % m ) % m (a \ / \ b) \% m \neq (a \% m \ / \ b \% m) \%m (a / b)%m=(a%m / b%m)%m
- 例如, ( 8 / 2 ) % 7 = 4 (8 / 2) \% 7 = 4 (8/2)%7=4,而 ( 8 % 7 ) / ( 2 % 7 ) % 7 = 0 (8 \% 7) / (2 \% 7) \% 7 = 0 (8%7)/(2%7)%7=0
- 如果 b ∣ a b \mid a b∣a,则 ( a / b ) % m = ( ( a / b ) ∗ ( b ∗ b − 1 ) ) % m = ( a / b ∗ b ) ∗ ( b − 1 ) % m = ( a ∗ b − 1 ) % m (a \ / \ b) \% m = ((a \ / \ b) * (b * b^{-1})) \% m = (a / b * b) * (b^{-1}) \% m = (a * b^{-1}) \% m (a / b)%m=((a / b)∗(b∗b−1))%m=(a/b∗b)∗(b−1)%m=(a∗b−1)%m。这样我们就把除法取余运算转化成了乘法取余运算。
- 例如,求3的幂的和