Files
python/TangDou/AcWing/ExGcd/877.md
HuangHai 1f397eca87 'commit'
2025-08-30 18:35:01 +08:00

5.0 KiB
Raw Blame History

##AcWing 877. 扩展欧几里得算法

一、题目描述

给定 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

输入样例

2
4 6
8 18

输出样例

-1 1
-2 1

样例理解:

  • 2x+3y=1 一组可行解:(-1,1)
  • 8x+18y=2 一组可行解:(-2,1)

二、裴蜀定理

裴蜀定理

若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$也是一组整数解。

注意:如果一个二元一次方程有正整数解,那么不只是一组解

####再举栗子 4x+2y=5 有没有整数解呢?没有,因为$a=4,b=2,m=5,gcd(4,2)=2,5$是除不开$2$的,所以没有整数解!

如何求贝祖数?

什么是贝祖数?

比如:$2x+y=3$,那么符合这个等式的x=1,$y=1$就是一组 贝祖数

可以使用 扩展欧几里得算法求贝祖数

举个栗子: 求 104x+40y=8 ,有没有合适的x,y,也就是求贝祖数

通过贝祖定理看一下,它是不是有解: gcd(104,40)=8,$8$是$8$的倍数,所以此方程一定有解,那么解是什么呢?

QQ截图20210301141004.png

扩展欧几里得算法的推导过程:

在$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

三、实现代码

#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'