目录
一、裴蜀定理的定义
裴蜀定理(也叫贝祖定理)(Bézout’s identity)简单来说就是:对于两个整数 ( a ) 和 ( b ),它们的最大公约数 ( d ) 可以表示成 ( a ) 和 ( b ) 的线性组合。也就是说,一定存在整数 ( x ) 和 ( y ),使得:
a x + b y = d ax + by = d ax+by=d
示例:
假设 ( a = 15 ) 和 ( b = 10 )。它们的最大公约数是 5,也就是 ( gcd(15, 10) = 5 ) 。根据裴蜀定理,应该存在一些整数 ( x ) 和 ( y ),使得:
15 x + 10 y = 5 15x + 10y = 5 15x+10y=5
事实上,( x = 1 ) 和 ( y = -1 ) 就是满足这个等式的一组解,因为:
15 ⋅ 1 + 10 ⋅ ( − 1 ) = 15 − 10 = 5 15 \cdot 1 + 10 \cdot (-1) = 15 - 10 = 5 15⋅1+10⋅(−1)=15−10=5
通过这个例子我想表示:任何两个整数的最大公约数都可以写成这两个整数的某种倍数之和。
另外如果已知整数(a)和(b),那么gcd(a,b)
以及对应的系数 x 和 y 是很好求解的。
注意:GCD 是 Greatest Common Divisor 的缩写,意思是最大公约数。
gcd(a,b)
就是a和b的最大公约数。
二、欧几里得算法
这不讲裴蜀定理呢,怎么冒出个欧几里得算法???
实际上裴蜀定理和欧几里得算法之间的关系还是很紧密的;可以通过欧几里得算法求解裴蜀定理中的a和b对应的系数x
和y
,以及它们的最大公约数gcd(a,b)
;接下来我会通过Java代码来演示如何求解gcd(a,b)、x、y。
1. 求解gcd(a,b)
gcd(a,b)的定义
给定两个整数a和b,gcd(a,b)是a和b的最大公约数。也就是说gcd(a,b)是既满足可以整除a又满足可以整除b的最大的整数。此外,gcd(a,b)一定是一个非负数。
示例:
- 给定 ( a = 12 ) 和 ( b = 18 )
- ( 12 ) 的正约数有:( 1, 2, 3, 4, 6, 12 )
- ( 18 ) 的正约数有:( 1, 2, 3, 6, 9, 18 )
- 这两个数的公共约数是 ( 1, 2, 3, 6 ),其中最大的公共约数是 ( 6 )
所以,gcd(12, 18) = 6
代码求解gcd(a,b)
import java.util.Scanner;
import java.lang.Math;
public class Test {
private static int getGcd(int a,int b){
//如果b是0,那么a的绝对值就是最大公约数
if(b==0)return Math.abs(a);
//b!=0就一直递归
else return getGcd(b,a%b);
}
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
int gcd=getGcd(in.nextInt(),in.nextInt());
System.out.println(gcd);
}
}
2、求解x和y
可以根据欧几里得算法,也就是上面的递归,持续跟踪系数x和y。
首先我们创建一个类来存储每次递归a和b对应的最大公约数以及两个系数:
//裴蜀定理:ax + by = gcd(a,b);
static class ResultGCD{
int gcd;
int x;
int y;
public ResultGCD(int gcd, int x, int y) {
this.gcd = gcd;
this.x = x;
this.y = y;
}
}
然后对getGcd函数进行修改:
private static ResultGCD getGcd(int a, int b){
//a*1 + b*0 = gcd(a,b) = a;
if(b==0)return new ResultGCD(a,1,0);
else{
//对应的a=a b=a%b!!!
ResultGCD result=getGcd(b,a%b);
//下面的6行代码如果初次接触,可能就看不懂了
int x1=result.x;
int y1=result.y;
int gcd=result.gcd;
int x=y1;
int y=x1-(a/b)*y1;
return new ResultGCD(gcd,x,y);
}
}
上面的6行代码是根据简单的数学公式推导过来的,具体推导步骤如下:
推导步骤
假设我们已经得到了较小规模问题的解,即对于b和a%b,有:
b ⋅ x 1 + ( a % b ) ⋅ y 1 = gcd ( b , a % b ) b \cdot x_1 + (a \% b) \cdot y_1 = \gcd(b, a \% b) b⋅x1+(a%b)⋅y1=gcd(b,a%b)
根据模运算的定义,
a
%
b
=
a
−
(
a
b
)
⋅
b
a \% b = a - \left( \frac{a}{b} \right) \cdot b
a%b=a−(ba)⋅b 例如:
(
11
%
5
=
11
−
(
11
5
)
⋅
5
)
(11 \% 5 = 11 - \left( \frac{11}{5} \right) \cdot 5)
(11%5=11−(511)⋅5);
所以上面的等式可以写成:
b x 1 + ( a − ( a b ) b ) y 1 = gcd ( a , b ) b x_1 + \left(a - \left(\frac{a}{b}\right) b \right) y_1 = \text{gcd}(a, b) bx1+(a−(ba)b)y1=gcd(a,b)
展开后得到:
a y 1 + b ( x 1 − ( a b ) y 1 ) = gcd ( a , b ) a y_1 + b \left(x_1 - \left(\frac{a}{b}\right) y_1 \right) = \text{gcd}(a, b) ay1+b(x1−(ba)y1)=gcd(a,b)
因此,解可以递推为:
x = y 1 x = y_1 x=y1
y = x 1 − ( a b ) y 1 y = x_1 - \left(\frac{a}{b}\right) y_1 y=x1−(ba)y1
代码中的推导
在代码中,这一步对应于以下几行:
ResultGCD result=getGcd(b,a%b);
int x1=result.x;
int y1=result.y;
int gcd=result.gcd;
int x = y1;
int y = x1 - (a / b) * y1;
return new ResultGCD(gcd,x,y);
总的来说,推导方式还是很简单,把%运算替换一下就成了。但如果不太理解可以把上面求解x和y的公式记下来也没问题。
求解gcd(a,b)、x、y的完整代码
import java.util.Scanner;
import java.lang.Math;
public class Test {
static class ResultGCD{
int gcd;
int x;
int y;
public ResultGCD(int gcd, int x, int y) {
this.gcd = gcd;
this.x = x;
this.y = y;
}
}
private static ResultGCD getGcd(int a, int b){
//a*1 + b*0 = gcd(a,b) = Math.abs(a);
if(b==0)return new ResultGCD(Math.abs(a),1,0);
else{
//对应的a=a b=a%b!!!
ResultGCD result=getGcd(b,a%b);
//下面的6行代码如果初次接触,可能就看不懂了
int x1=result.x;
int y1=result.y;
int gcd=result.gcd;
int x=y1;
int y=x1-(a/b)*y1;
return new ResultGCD(gcd,x,y);
}
}
public static void main(String[] args) {
Scanner in=new Scanner(System.in);
ResultGCD ans=getGcd(in.nextInt(),in.nextInt());
System.out.println("gcd="+ans.gcd);
System.out.println("x="+ans.x);
System.out.println("y="+ans.y);
}
}
三、裴蜀定理的推论
裴蜀定理的结论
对于任意整数 (a) 和 (b),存在整数 (x) 和 (y),使得:
a
x
+
b
y
=
gcd
(
a
,
b
)
ax + by = \gcd(a, b)
ax+by=gcd(a,b)
1. 可整除性条件
对于任意整数 (a) 和 (b),如果 (d = gcd(a, b)),那么对于任意整数 (k),存在整数 (x) 和 (y) 使得:
a
x
+
b
y
=
k
当且仅当
k
是
d
的倍数
ax + by = k \quad \text{当且仅当} \quad k \text{是} d \text{的倍数}
ax+by=k当且仅当k是d的倍数
2. 互质与最大不能表示数
若
d
=
gcd
(
a
,
b
)
d= \gcd(a, b)
d=gcd(a,b) 并且
d
=
1
d=1
d=1,那么a和b一定互质。且存在一个正整数
M
A
X
MAX
MAX ,
M
A
X
MAX
MAX是a和b的线性组合最大不能表示的整数。换句话说,任何大于
M
A
X
MAX
MAX的整数都可以通过a
和b
的线性组合表示。 其中:
M
A
X
=
a
b
−
a
−
b
MAX=ab-a-b
MAX=ab−a−b
3. 两数之和构成的整数集合
若 (a) 和 (b) 互质(即 (gcd(a, b) = 1)),则所有形如 (ax + by) 的整数(其中 (x) 和 (y) 为整数)构成了所有整数集合。这意味着我们可以用 (a) 和 (b) 的线性组合来表示任意整数。
4. 多个整数的扩展
裴蜀定理和欧几里得算法不止是适用于二元组,涉及多个整数的仍然成立。