裴蜀定理+扩展欧几里得 详解

\(\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;
}
posted @ 2021-02-28 19:36  栾竹清影  阅读(566)  评论(0编辑  收藏  举报