裴蜀定理+扩展欧几里得 详解
\(\texttt{例题}\)
已知正整数 \(a,b\) ,求满足 \(ax+by=gcd(a,b)\) 的整数 \(x,y\)。
\(\texttt{为何 ax+by=gcd(a,b) 有正整数解(裴蜀定理证明)?}\)
我们设 \(ax+by\) (\(x,y\) 为整数)的最小正整数值为 \(s\),\(t\) 为 \(gcd(a,b)\);
再设 \(p,r\) 使得 \(a/s=p\) …… \(r\) ,得:
\(r=a-ps\)
\(∵s=ax+by\)
\(∴r=a-p(ax+by)\)
\(∴r=a-pxa-pby\)
\(∴r=(1-px)a+(-pb)y\)
设 \(x^{'}=(1-px),y^{'}=(-pb)\) 可得 \(r\) 也是 \(ax+by\) 的一个整数值。
又 \(∵s\) 是式子 \(ax+by\) 的最小正整数值
\(∴r=0\) (\(r\) 是余数,它不能是负数且小于 \(s\))
\(∴s|a\)
按照以上的方法同理可得: \(s|b\)
则 \(s|a,s|b\),即 \(s\) 是 \(a,b\) 的公因数,得
\(\quad\quad s≤t\quad\)① 。
\(∵t|a,t|b\)
\(∴t|ax,t|by\)
\(∴t|ax+by,t|s,\)
\(\quad\quad t≤s\quad\)②
由 \(①,②\) 可知:\(t=s\)
因此,式子成立。
\(\texttt{如何求gcd(a,b),x,y(扩展欧几里得)}\)
求 \(gcd(a_1,b_1)\),我们可以用辗转相除法,即:
\(gcd(a_1,b_1)=gcd(b_1,a_1\%b_1)=gcd(b_2,a_2\%b_2)=\) …… \(=gcd(gcd(a_{m-1},b_{m-1}),0)\)
\(\quad\quad\quad\quad\quad\quad\quad\quad↓\quad\quad↓\quad\quad\quad\quad\quad↓\quad\quad↓\quad\quad\quad\quad\quad\quad\quad\quad↓\quad\quad\quad\quad\quad ↓\)
\(\quad\quad\quad\quad\quad\quad\quad\quad a_2\quad\ b_2\quad\quad\quad\quad\quad a_3 \quad\quad b_3\quad\quad\quad\quad\quad\quad\quad a_m\quad\quad\quad\quad\quad b_m\)
不难发现,对于任意的 \(k(1≤k≤m)\) , \(gcd(a_1,b_1)=gcd(a_k,b_k)\),则 \(a_kx_k+b_k y_k=gcd(a_1,b_1)\) 有整数解。那 \(x_k\) 与 \(x_{k-1}\)、\(y_k\) 与 \(y_{k-1}\) 是否有什么关系呢?
\(∵a_kx_k+b_k y_k=gcd(a,b),a_{k+1}x_{k+1}+b_{k+1}y_{k+1}=gcd(a,b)\)
\(∴a_kx_k+b_k y_k=a_{k+1}x_{k+1}+b_{k+1}y_{k+1}\)
\(∵b_{k+1}=a_{k}\%b_{k},a_{k+1}=b_k\)
\(∴a_kx_k+b_k y_k=b_{k}x_{k+1}+(a_k\%b_k)y_{k+1}\)
\(a_kx_k+b_k y_k=b_{k}x_{k+1}+(a_k-b_k\lfloor \dfrac{a_k}{b_k}\rfloor)y_{k+1}\)
\(a_kx_k+b_k y_k=b_{k}x_{k+1}+a_ky_{k+1}-b_k\lfloor \dfrac{a_k}{b_k}\rfloor y_{k+1}\)
\(a_kx_k+b_k y_k=a_ky_{k+1}+b_{k}(x_{k+1}-\lfloor \dfrac{a_k}{b_k}\rfloor y_{k+1})\)
\(a_kx_k=a_ky_{k+1},b_ky_k=b_{k}+(x_{k+1}-\lfloor \dfrac{a_k}{b_k}\rfloor y_{k+1})\)
得:
\(\begin{cases}x_k=y_{k+1}\\ y_k=x_{k+1}-\lfloor \dfrac{a_k}{b_k}\rfloor y_{k+1}\end{cases}\)
\(∵b_m=0,a_m=gcd(a_{m-1},b_{m-1})=gcd(a_1,b_1)\)
(辗转相除原理)
\(∴x_m=1,y_m=0\) 能满足 \(a_mx_m+b_my_m=gcd(a_1,b_1)\)
则可根据:
\(\begin{cases}x_k=y_{k+1}\\ y_k=x_{k+1}-\lfloor a_k/b_k\rfloor y_{k+1}\end{cases}\quad\begin{cases}x_m=1\\ y_m=0\end{cases}\)
倒推出 \(x_1,y_1\)。
\(\texttt{代码实现}\)
#include<bits/stdc++.h>
using namespace std;
void exgcd(int a,int b,int &x,int &y,int &gcd)
{
if(!b)
{
x=1,y=0,gcd=a;
return ;
}
exgcd(b,a%b,x,y,gcd);
register int tmp=y;
y=x-(a/b)*y,x=tmp;
}
int main()
{
int a,b,x,y,gcd;
scanf("%d%d",&a,&b);
exgcd(a,b,x,y,gcd);
printf("%d,%d\n",x,y);
return 0;
}