P1 拓展欧几里得
已知二元不定方程,其中 a , b a,b a,b 为常数
a x + b y = c ( a , b ∈ Z ) ax+by=c(a,b\in Z) ax+by=c(a,b∈Z)
若令 k = gcd ( a , b ) k=\gcd (a,b) k=gcd(a,b) ,则有 k ∣ ( a x + b y ) k|(ax+by) k∣(ax+by)
显然,只有 k ∣ c k|c k∣c 时,不定方程才有整数解。
只需要求出
a
x
+
b
y
=
k
ax+by=k
ax+by=k
的一组特解,我们设其为
x
0
x_0
x0 与
y
0
y_0
y0,则有:
a
x
0
+
b
y
0
=
k
ax_0+by_0=k
ax0+by0=k
a
x
0
c
k
+
b
y
0
c
k
=
k
a\frac {x_0c}{k}+b\frac{y_0c}{k}=k
akx0c+bky0c=k
那么 a x + b y = c ax+by=c ax+by=c 的一组解则为: x = x 0 c k , y = y 0 c k x=\frac {x_0c}{k},y=\frac{y_0c}{k} x=kx0c,y=ky0c
那么怎么求
a
x
+
b
y
=
k
ax+by=k
ax+by=k 的解呢,我们把
k
=
gcd
(
a
,
b
)
k=\gcd(a,b)
k=gcd(a,b) 换回:
a
x
+
b
y
=
gcd
(
a
,
b
)
ax+by=\gcd(a,b)
ax+by=gcd(a,b)
若
a
≤
b
a\leq b
a≤b ,由欧几里得定理得:
gcd
(
a
,
b
)
=
gcd
(
b
,
a
%
b
)
\gcd(a,b)=\gcd(b,a \%b)
gcd(a,b)=gcd(b,a%b)
其中
%
\%
% 为取模运算,设
x
1
x_1
x1,
y
1
y_1
y1 满足:
x
1
b
+
y
1
(
a
%
b
)
=
gcd
(
b
,
a
%
b
)
x_1b+y_1(a \% b)= \gcd(b,a \% b)
x1b+y1(a%b)=gcd(b,a%b)
则:
a
x
+
b
y
=
x
1
b
+
y
1
(
a
%
b
)
ax+by=x_1b+y_1(a \% b)
ax+by=x1b+y1(a%b)
由取模的意义得:
a x + b y = x 1 b + y 1 ( a − b ∗ ⌊ a b ⌋ ) ax+by=x_1b+y_1(a-b*\lfloor \frac{a}{b}\rfloor) ax+by=x1b+y1(a−b∗⌊ba⌋)
化简得:
a
x
+
b
y
=
y
1
a
+
b
(
x
1
−
⌊
a
b
⌋
y
1
)
ax+by=y_1a+b(x_1-\lfloor\frac {a}{b}\rfloor y_1)
ax+by=y1a+b(x1−⌊ba⌋y1)
则一定有一组解为
x
=
y
1
,
y
=
x
1
−
⌊
a
b
⌋
y
1
x=y_1,y=x_1-\lfloor\frac {a}{b}\rfloor y_1
x=y1,y=x1−⌊ba⌋y1
则问题已经转化为求
b
x
+
(
a
%
b
)
y
=
gcd
(
b
,
a
%
b
)
bx+(a \% b)y= \gcd(b,a \% b)
bx+(a%b)y=gcd(b,a%b)
的解
很明显,这是一个递归,那么跳出条件是什么呢?
当
b
=
0
b=0
b=0 时,一定有一组解
x
=
1
,
y
=
0
x=1,y=0
x=1,y=0 满足
a
x
=
g
c
d
(
a
,
0
)
ax=gcd(a,0)
ax=gcd(a,0)
注:
g
c
d
(
0
,
k
)
=
k
(
k
∈
Z
)
gcd(0,k)=k(k\in Z)
gcd(0,k)=k(k∈Z)
代码:
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=1,y=0;
return;
}
else
{
int tmp=x;
x=y;
y=tmp+(a/b)*y
}
}