裴蜀等式
对于任何整数 $a$、$b$ 和它们的最大公约数 $d$,关于未知数 $x$ 和 $y$ 的线性丢番图方程称为裴蜀等式
$$ax+by=m$$ 有整数解时当且仅当 $m$ 是 $d$ 的倍数
裴蜀等式有解时必然有无穷多个整数解,每组解 $x$、$y$ 都成为裴蜀数,$x$ 和 $y$ 可用扩展欧几里得算法 $(Extended\ Euclidean\ algorithm)$ 求得
特别地,$ax+by=1$ 有整数解,当且仅当 $a$ 和 $b$ 互素
拓展欧几里得算法
欧几里得算法地终止状态是 $a=gcd,b=0$,那么此时方程 $ax+by=gcd$ 的解 $x=1,y$ 为任意数
当然,上面说的是最终状态,但是我们能否从最终状态反推初始状态?
假设当前要求的是 $a$ 和 $b$ 的最大公约数,并求出 $x$ 和 $y$,使得 $ax+by=gcd・・・・(Formula\ 1)$
而我们已经求出了下一状态 $b$ 和 $a\% b$ 的最大公约数,并且也求出了一组解 $x_1$ 和 $y_1$,使得 $b\times x_1 + (a\% b)\times y_1 = gcd$
那么这两个状态之间是否存在某种关系呢?
我们知道 $a\% b = a - (a/b)\times b$(这里的 /
指的是整除),那么可以进一步得到:
$$ \begin{equation}\begin{split} gcd&=b\times x_1+(a-(a/b)\times b)\times y_1 \\ &=b\times x_1+a\times y_1 - (a/b) \times b \times y_1\\ &=a\times y_1 + b\times (x_1-a/b\times y_1)···(Formula\ 2) \end{split}\end{equation} $$
对比 $Formula\ 1$ 和 $Formula\ 2$,我们发现一个递推式
$$ \begin{equation}\begin{split} &x = y_1\\ &y = x_1 - a/b\times y_1 \end{split}\end{equation} $$
其中,$x$ 和 $y$ 分别是递归时第 $i$ 层 $ax+by=gcd$ 的一组解,$x_1$ 和 $y_1$ 分别是递归时第 $i+1$ 层 $ax_1+by_1=gcd$ 的一组解
我们上面推到的其实都是 $ax+by=d$ 的解,$d=gcd (a,b)$,对于一般的情况 $m$ 为 $d$ 的倍数,则有 $ax+by=m$ 的解为 $x \times \frac {m}{d}$ 和 $y \times \frac {m}{d}$
- public class exgcd {
- static long x, y;
- static long exgcd(long a, long b) {
- if (b == 0) {
- x = 1;
- y = 0;
- return a;
- }
- long res = exgcd(b, a % b);
- long x1 = x;
- x = y;
- y = x1 - (a / b) * y;
- return res;
- }
- /*
- * 线性方程 ax + by = m 当m为gcd(a,b)的倍数时有整数解
- */
- static long linearEquation(long a, long b, long m) throws Exception {
- long d = exgcd(a, b);
- if (m % d != 0)
- throw new Exception("无解");
- long n = m / d;
- x *= n;
- y *= n;
- return d;
- }
-
- public static void main(String[] args) {
- try {
- linearEquation(2, 7, 1);
- System.out.println(x + " " + y);
- } catch (Exception e) {
- System.out.println("无解");
- }
- }
- }