|
|
|
|
##[$AcWing$ $877$. 扩展欧几里得算法](https://www.acwing.com/problem/content/description/879/)
|
|
|
|
|
|
|
|
|
|
### 一、题目描述
|
|
|
|
|
给定 $n$ 对正整数 $a_i,b_i$,对于每对数,求出一组 $x_i,y_i$,使其满足 $a_i×x_i+b_i×y_i=gcd(a_i,b_i)$。
|
|
|
|
|
|
|
|
|
|
**输入格式**
|
|
|
|
|
|
|
|
|
|
第一行包含整数 $n$。
|
|
|
|
|
|
|
|
|
|
接下来 $n$ 行,每行包含两个整数 $a_i,b_i$。
|
|
|
|
|
|
|
|
|
|
**输出格式**
|
|
|
|
|
输出共 $n$ 行,对于每组 $a_i,b_i$,求出一组满足条件的 $x_i,y_i$,每组结果占一行。
|
|
|
|
|
|
|
|
|
|
本题答案不唯一,输出任意满足条件的 $x_i,y_i$ 均可。
|
|
|
|
|
|
|
|
|
|
**数据范围**
|
|
|
|
|
$1≤n≤10^5$
|
|
|
|
|
$1≤a_i,b_i≤2×10^9$
|
|
|
|
|
|
|
|
|
|
**输入样例**
|
|
|
|
|
```cpp {.line-numbers}
|
|
|
|
|
2
|
|
|
|
|
4 6
|
|
|
|
|
8 18
|
|
|
|
|
```
|
|
|
|
|
**输出样例**
|
|
|
|
|
```cpp {.line-numbers}
|
|
|
|
|
-1 1
|
|
|
|
|
-2 1
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
<font color='red' size=4><b>样例理解:
|
|
|
|
|
- $2x+3y=1$ 一组可行解:$(-1,1)$
|
|
|
|
|
- $8x+18y=2$ 一组可行解:$(-2,1)$
|
|
|
|
|
</b></font>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 二、[裴蜀定理](https://baike.baidu.com/item/%E8%A3%B4%E8%9C%80%E5%AE%9A%E7%90%86/5186593?fr=aladdin)
|
|
|
|
|
|
|
|
|
|
#### 裴蜀定理
|
|
|
|
|
若$a$,$b$是整数,且$gcd(a,b)=d$,那么:
|
|
|
|
|
|
|
|
|
|
- 对于任意的整数$x$,$y$,$ax+by$都一定是$d$的倍数
|
|
|
|
|
|
|
|
|
|
- 一定存在整数$x$,$y$,使$ax+by=d$成立
|
|
|
|
|
|
|
|
|
|
#### 裴蜀定理推论
|
|
|
|
|
|
|
|
|
|
$a,b$互质 $\Leftrightarrow $ $gcd(a,b)=1$ $\Leftrightarrow $ 存在整数$x$,$y$,使得$ax+by=1$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### 举栗子
|
|
|
|
|
$2x+y=3$
|
|
|
|
|
|
|
|
|
|
那么$a=2$,$b=1$,$m=3$,$gcd(2,1)=1$,$3$是$1$的倍数,所以这个方程一定有整数解。
|
|
|
|
|
|
|
|
|
|
$x=1$,$y=1$就是一个整数解,还可以有$x=-2$,$y=7$也是一组整数解。
|
|
|
|
|
|
|
|
|
|
<font color='red' size=4><b>注意:如果一个二元一次方程有正整数解,那么不只是一组解</b></font>
|
|
|
|
|
|
|
|
|
|
####再举栗子
|
|
|
|
|
$4x+2y=5$
|
|
|
|
|
有没有整数解呢?没有,因为$a=4,b=2,m=5,gcd(4,2)=2,5$是除不开$2$的,所以没有整数解!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### [如何求贝祖数?](https://www.bilibili.com/video/av77974575/)
|
|
|
|
|
什么是贝祖数?
|
|
|
|
|
|
|
|
|
|
比如:$2x+y=3$,那么符合这个等式的$x=1$,$y=1$就是一组 **贝祖数**
|
|
|
|
|
|
|
|
|
|
可以使用 **扩展欧几里得算法求贝祖数**
|
|
|
|
|
|
|
|
|
|
**举个栗子**:
|
|
|
|
|
求 $104x+40y=8$ ,有没有合适的$x,y$,也就是求贝祖数
|
|
|
|
|
|
|
|
|
|
通过贝祖定理看一下,它是不是有解: $gcd(104,40)=8$,$8$是$8$的倍数,所以此方程一定有解,那么解是什么呢?
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
**扩展欧几里得算法的推导过程:**
|
|
|
|
|
|
|
|
|
|
在$exgcd$中,我们实际是求不定方程$ax+by=gcd(a,b)$,并且,我们所返回的值,是这组解$(x,y)$的最大公因数$gcd(x,y)$。
|
|
|
|
|
|
|
|
|
|
所以我们最后得到的解,要通过$X=x∗k/gcd(a,b),Y=(k−a∗x)/gcd(a,b)$来进行一个小小的转换,得到一组解
|
|
|
|
|
|
|
|
|
|
### 算法实现过程证明
|
|
|
|
|
|
|
|
|
|
#### ($1$)、当 $b=0$时
|
|
|
|
|
|
|
|
|
|
$\large ax+by=gcd(a,0)$,也就是:$\large ax=gcd(a,0)=a$,所以$\large x=1$。
|
|
|
|
|
|
|
|
|
|
那么$y$呢?因为普遍意义上的求贝祖数,一般是指不小于零的一组解,那么不小于$0$的第一个可能$y$值就是:$y=0$,所以,可以将$x=1,y=0$做为一组特解返回,也就是返回了一组**不小于零的贝祖数**。
|
|
|
|
|
|
|
|
|
|
#### ($2$)、当 $b≠0$时
|
|
|
|
|
|
|
|
|
|
$\because ax+by=gcd(a,b)$ 【原计算式】
|
|
|
|
|
|
|
|
|
|
$gcd(b,a\%b)=gcd(a,b)$ 【辗转相除法】
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$\therefore ax+by=gcd(a,b)=gcd(b,a\%b)=b\cdot x_0+(a\%b)\cdot y_0$ ① 【变量互换,最终是一致滴~】
|
|
|
|
|
|
|
|
|
|
$\because a\%b=a-⌊\frac{a}{b}⌋\cdot b$ ②【用整除向下取整来描述扣去$a$中所有的$b$,剩下的就是余数】
|
|
|
|
|
|
|
|
|
|
将②代入①
|
|
|
|
|
$\therefore ax+by=bx_0+(a-⌊\frac{a}{b}⌋\cdot b)\cdot y_0$
|
|
|
|
|
|
|
|
|
|
$\therefore ax+by=ay_0+b(x_0-⌊\frac{a}{b}⌋\cdot y_0)$
|
|
|
|
|
|
|
|
|
|
$\therefore x=y_0,y=x_0-⌊\frac{a}{b}⌋y_0$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### 三、实现代码
|
|
|
|
|
```cpp {.line-numbers}
|
|
|
|
|
#include <bits/stdc++.h>
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
int exgcd(int a, int b, int &x, int &y) {
|
|
|
|
|
if (!b) {
|
|
|
|
|
x = 1, y = 0;
|
|
|
|
|
return a;
|
|
|
|
|
}
|
|
|
|
|
int d = exgcd(b, a % b, y, x);
|
|
|
|
|
y -= a / b * x;
|
|
|
|
|
return d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
|
int n;
|
|
|
|
|
cin >> n;
|
|
|
|
|
while (n--) {
|
|
|
|
|
int a, b;
|
|
|
|
|
cin >> a >> b;
|
|
|
|
|
int x, y;
|
|
|
|
|
exgcd(a, b, x, y);
|
|
|
|
|
printf("%d %d\n", x, y);
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 四、三者之间的关系
|
|
|
|
|
|
|
|
|
|
#### 1. 裴蜀定理
|
|
|
|
|
- 对于任意一对正整数$a,b$,一定存在非零整数$x,y$使得$ax+by=gcd(a,b)$
|
|
|
|
|
|
|
|
|
|
- 可以用来判断方程$ax+by=c$是否有解,只要看$c$是否是$gcd(a,b)$的倍数
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### 2. 扩展欧几里得算法
|
|
|
|
|
如果方程$ax+by=c$有解,那么扩欧可以求方程$ax+by=gcd(a,b)$一组解($x_0,y_0$)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### 3.线性同余方程
|
|
|
|
|
给定$a,b,m$构造出$x$使得$ax≡b(mod\ m)$成立
|
|
|
|
|
|
|
|
|
|
$ax≡b(mod\ m)⟺ax=my+b$($y$是整数)
|
|
|
|
|
|
|
|
|
|
由此可知$ax−my=b$
|
|
|
|
|
|
|
|
|
|
令$y'=−y$则有$ax+my'=b$
|
|
|
|
|
|
|
|
|
|
则构造$x$一定使得$ax+my'=b$有解
|
|
|
|
|
|
|
|
|
|
根据裴蜀定理可知该方程有解的充要条件是$(a,m)|b$
|
|
|
|
|
|
|
|
|
|
设$d=(a,m)$,若$d∤b$则$x$不存在
|
|
|
|
|
|
|
|
|
|
若$d|b$,则可以用 **扩展欧几里得算法** 算出$ax+bm=gcd(a,m)=d$的$x_0,y_0$
|
|
|
|
|
|
|
|
|
|
再将$x_0×\frac{b}{d},y_0×\frac{b}{d}$得到$x$与$y'$
|