扩展欧几里得算法
问题描述
给定
n
n
n对正整数
a
i
,
b
i
a_i,b_i
ai,bi,对于每一对数,求出一组
x
i
,
y
i
x_i,y_i
xi,yi,使其满足
a
i
x
i
+
b
i
y
i
=
g
c
d
(
a
,
b
)
a_ix_i+b_iy_i=gcd(a,b)
aixi+biyi=gcd(a,b)
0.裴蜀定理
对于整数
a
,
b
a,b
a,b 有
d
=
g
c
d
(
a
,
b
)
d=gcd(a,b)
d=gcd(a,b)则对于任何的整数
x
,
y
x,y
x,y则一定有
d
∣
a
x
+
b
y
d|ax+by
d∣ax+by,即
a
x
+
b
y
ax+by
ax+by一定是
g
c
d
(
a
,
b
)
gcd(a,b)
gcd(a,b)的倍数,特别的,一定存在整数
x
,
y
x,y
x,y使得
a
x
+
b
y
=
g
c
d
(
a
,
b
)
ax+by=gcd(a,b)
ax+by=gcd(a,b)成立。
如果
a
x
+
b
y
=
t
ax+by=t
ax+by=t,而
t
t
t不能被
d
d
d整除,则该方程无整数解。
1.扩展欧几里得
用于求解方程 a x + b y = g c d ( a , b ) ax+by=gcd(a,b) ax+by=gcd(a,b)的解
当 b ≠ 0 b\neq0 b=0时,因为 g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b)=gcd(b,a\%b) gcd(a,b)=gcd(b,a%b)则有
b
x
′
+
(
a
%
b
)
y
′
=
g
c
d
(
b
,
a
%
b
)
(1)
\\bx'+(a\%b)y'=gcd(b,a\%b)\tag{1}
bx′+(a%b)y′=gcd(b,a%b)(1)
易得
a
%
b
=
a
−
⌊
a
/
b
⌋
∗
b
a\%b=a-\lfloor a/b \rfloor*b
a%b=a−⌊a/b⌋∗b,将其带入
(
1
)
(1)
(1)式中可得
b
x
′
+
(
a
−
⌊
a
b
⌋
∗
b
)
y
′
=
g
c
d
(
b
,
a
%
b
)
b
(
x
′
−
⌊
a
b
⌋
)
+
a
y
′
=
g
c
d
(
b
,
a
%
b
)
bx'+(a-\lfloor \frac{a}{b} \rfloor*b)y'=gcd(b,a\%b) \\b(x'-\lfloor \frac{a}{b} \rfloor)+ay'=gcd(b,a\%b)
bx′+(a−⌊ba⌋∗b)y′=gcd(b,a%b)b(x′−⌊ba⌋)+ay′=gcd(b,a%b)
由此可得
{
x
=
y
′
y
=
x
′
−
⌊
a
b
⌋
∗
y
′
(2)
\left\{ \begin{array}{c}\tag{2} x=y' \\ y=x'-\lfloor \frac{a}{b} \rfloor *y'\\ \end{array} \right.
{x=y′y=x′−⌊ba⌋∗y′(2)
观察原有的欧几里得算法
int gcd(int a,int b)
{
if(!b){
return a;
}
return gcd(b,a%b);
}
我们所要求的
x
,
y
x,y
x,y在每一步的辗转相除中都会改变,但在最后一步,递归的出口一定是
x
=
1
,
y
=
0
x=1,y=0
x=1,y=0。因为在辗转相除法的最后一步,
b
b
b一定等于
0
0
0且返回值
a
a
a即为所求的最大公约数,即
a
∗
x
+
0
∗
y
=
g
c
d
(
a
,
0
)
=
a
a*x+0*y=gcd(a,0)=a
a∗x+0∗y=gcd(a,0)=a
因此必有特解
x
=
1
,
y
=
0
x=1,y=0
x=1,y=0 这里注意一下
x
x
x是只能取
1
1
1,但是
y
y
y可以取任何值,为了计算方便我们将其取做
0
0
0。
由刚刚推导的
(
2
)
(2)
(2)我们可以知道,每一步的
x
x
x和
y
y
y都与下一步的
x
′
,
y
′
x',y'
x′,y′以上述公式的方式相联系,因此我们可以修改一下
g
c
d
gcd
gcd函数便可以得到一段很漂亮简洁的代码。
int exgcd(int a,int b,int &x,int &y)
{
if(!b)
{
x=1,y=0;
return a;
}
int d,x1,y1; //我们需要用到从上一层递归栈中传过来的d,x1,y1因此这里的x和y都要传地址
d=exgcd(b,a%b,x1,y1);
x = y1;
y = x1 - (a/b)*y1;
return d;
}
2.对于求解更一般的方程 a x + b y = c ax+by=c ax+by=c
设
d
=
g
c
d
(
a
,
b
)
d=gcd(a,b)
d=gcd(a,b),该式成立当且仅当
d
∣
c
d | c
d∣c
求解方法如下:
首先用扩展欧几里得算法求出
a
x
+
b
y
=
d
ax+by=d
ax+by=d的特解
设特解为
x
=
x
0
,
y
=
y
0
x=x_0,y=y_0
x=x0,y=y0 ,即
a
x
0
+
b
y
0
=
d
ax_0+by_0=d
ax0+by0=d
于是
a
x
+
b
y
=
c
ax+by=c
ax+by=c的特解为
a
x
0
(
c
/
d
)
+
b
y
0
(
c
/
d
)
=
c
ax_0(c/d)+by_0(c/d) = c
ax0(c/d)+by0(c/d)=c
通解=特解+齐次解
a
x
+
b
y
=
0
ax+by=0
ax+by=0的解为
x
=
b
/
d
,
y
=
−
a
/
d
x=b/d,y=-a/d
x=b/d,y=−a/d
因此一般形式的解为
x
=
x
0
(
c
/
d
)
+
k
∗
(
b
/
d
)
y
=
y
0
(
c
/
d
)
−
k
∗
(
a
/
d
)
x=x_0(c/d)+k*(b/d) \\y=y_0(c/d)-k*(a/d)
x=x0(c/d)+k∗(b/d)y=y0(c/d)−k∗(a/d)
这里注意一下为什么齐次解是
x
=
b
/
d
,
y
=
−
a
/
d
x=b/d,y=-a/d
x=b/d,y=−a/d而不是
x
=
b
,
y
=
−
a
x=b,y=-a
x=b,y=−a,因为显然前者在乘上
k
k
k后可以取到更多的值。
3.求解一次同余方程 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)|b
gcd(a,m)∣b
特别的,当
b
=
1
b=1
b=1且
a
,
m
a,m
a,m互质时所求的
x
x
x即为
a
a
a的逆元
因为
a
x
+
m
y
=
g
c
d
(
a
,
m
)
ax+my=gcd(a,m)
ax+my=gcd(a,m) 而
b
=
1
b=1
b=1 故
g
c
d
(
a
,
m
)
=
1
gcd(a,m)=1
gcd(a,m)=1 即
a
,
m
a,m
a,m 互质。