线性丢番图方程 裴蜀定理 扩展欧几里得算法
二元线性丢番图方程
方程 \(ax+by=c\) 称为二元线性丢番图方程,其中 \(a,b,c\) 为常量,\(x,y\) 为变量,问方程是否有整数解。
该方程实际上是二维平面上的一条直线,无固定解,所以丢番图方程又称为不定方程。
在数论中,我们记 \((a,b)\) 为 \(a\) 和 \(b\) 的最大公约数,即 \(gcd(a,b)\) 的简写。
那么,在讨论不定方程是否有整数解上,我们可得到以下定理。
裴蜀定理
如果 \(a,b\in N\) ,则有整数 \(x,y\) 使 \(ax+by=(a,b)\) 。
这个等式称为裴蜀等式。
推论
- 如果 \(a,b\in N\) ,且 \((a,b)=1\) ,当且仅当 \(\exists \ x,y\in N\) ,使 \(ax+by=1\) 。
- 如果 \(a,b\in N\) ,则有则有整数 \(x,y,n\) 使 \(ax+by=(a,b)\times n\) 。
证明
换个理解方式:对 \(\forall x,y\) ,\(d=ax+by\) ,\(d\) 一定是 \((a,b)\) 的整数倍;其中最小的 \(d\) 就是 \((a,b)\) 。
\(a,b\) 互质, 则 \(d=(a,b)=1\) ,所以 \(ax+by=1\) 。
那么,如果 \(d\) 不是 \((a,b)\) 的整数倍,不定方程一定没有整数解。
扩展欧几里得算法
问题1
求 \(ax+by=(a,b)\) 的一组整数解。
算法
当 \(b= 0\) 时,\(ax+by=a\) ,故而 \(x=1,\ y=0\) 。
当 \(b\ne 0\) 时,
由欧几里得算法,\((a,b)=(b,a\%b)\) 。
由裴蜀定理,
所以 \(x=y_1,\ y=x_1-\frac{a}{b}y_1\\\)。
利用递归,先求出下一层的 \(x_1,\ y_1\)。
再回代上一层,回代求特解 \(x_0, \ y_0\)。
tips
实际上,就是等式两边同时除以 \((a,b)\) ,得到 \(cx+dy=1\) 。
其中,\(c=\dfrac{a}{(a,b)},\ d=\dfrac{b}{(a,b)}\) ,可以直接写出通解 \(x=x_0+dn,\ y=y_0-cn\) 。
构造通解
问题2
求 \(ax+by=c\) 的一组整数解。
算法
当 \((a,b)\mid c\) ,则有整数解。
先用扩展欧几里得算法求 \(ax+by=(a,b)\) 的解。
再乘以 \(\dfrac{c}{(a,b)}\) ,即得到原方程的特解 \(x_0,\ y_0\)。(原理就是上面tips的逆运用)
当 \((a,b)\nmid c\) ,则无整数解。
[AcWing877] 扩展欧几里得算法
题目描述
给定 \(n\) 对正整数 \(a_i, b_i\),对于每对数,求出一组 \(x_i, y_i\),使其满足 \(a_i \times x_i + b_i \times 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 \le n \le 10^5\),
\(1 \le a_i,b_i \le 2 \times 10^9\)
输入样例:
2
4 6
8 18
输出样例:
-1 1
-2 1
算法
这里就用 \(a=4,\ b=6\) 来手推扩欧算法。
C++ 代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll exgcd(int a,int b,int &x,int &y)
{
if (b == 0){
x = 1, y = 0;
return a;
}
int x1, y1, gcd;
gcd = exgcd(b, a % b, x1, y1);
x = y1, y = x1 - a / b * y1;
return gcd;
}
int main()
{
int n; cin >> n;
while (n--){
int a, b, x, y;
cin >> a >> b;
int gcd = exgcd(a,b,x,y);
cout << x << " " << y << endl;
}
return 0;
}