扩展欧几里得算法,是用来求形如算法
的不定方程的整数解的。spa
根据裴蜀定理,若 \(gcd(a,b) \mid c\),则必定有整数解,不然必定无解。code
设 \(d=gcd(a,b)\),显然有 \(d \mid a,d \mid b\)。因为 \(x,y\) 都是整数,因此 \(d \mid (ax),d \mid (by)\)。
因此若是要让式子成立,\(c\) 必须得是 \(a,b\) 的公约数的倍数才对。
又由于 \(x,y\) 是整数,因此 \(c\) 必须是 \(a,b\) 的最大公约数的倍数才行。
实在看不懂的话感性理解下吧awa递归
让方程两边同除以 \(gcd(a,b)\),能够获得方程get
其中it
后面求特解中提到的方程均为转化后的方程,即后面方程中的 \(a\) 就是 \(a'\),\(b\) 就是 \(b'\)class
由欧几里得算法可知,\(gcd(a,b)=gcd(b,a \bmod b)\)
因而,咱们能够获得扩展
接下来咱们就要根据 \(x',y'\) 来反推 \(x,y\)。
由于 \(gcd(a,b)=gcd(b,a \bmod b)\),因此语法
咱们把右边的式子变形一下:gc
因此,\(x=y',y=x'-\left\lfloor\frac{a}{b}\right\rfloor y')\)。
因而咱们只要向欧几里得算法那样递归,就能获得一组特解了。
但还有一个问题,就是递归边界。
递归边界显然是 \(b=0\) 的状况,而此时的方程就变为:
因此此时 \(x=1\),\(y\) 是任意整数。
求解过程用代码写出来就是这个亚子:
ll exgcd(ll a,ll b,ll &x,ll &y) { if(b==0) { x=1; y=0;//y能够是任意整数,这里咱们让他等于0也能够 return a; } const ll m=exgcd(b,a%b,y,x); y-=(a/b)*x; return m; }
可是可是,这求的是
的解呀。不是咱们要的解。
由于咱们在转化时让方程两边都除以 \(\frac{c}{gcd(a,b)}\),因此如今要乘回来:
这里咱们设以前求出来的通解为 \(x_0,y_0\)。
设 \(d=gcd(a,b)\)
则通解
\(x=x_0+\frac{b}{d} \times t,y=y0-\frac{a}{d} \times t\)
t是任意整数。
为何是这样呢?
显然咱们须要知足
把 \(x,y\) 拆开来:
因而就有
又由于 \(n,m\) 必须是整数,因此只有上面说的那个能够知足要求了。
这里指 \(x\) 是最小正整数。
当咱们求出一组特解后,最小正整数解即
上面的式子用的是 C++ 语法。 求最小正整数解惯用手法,这里再也不累述。