2023-03-01 18:08阅读: 12评论: 0推荐: 0

扩展欧几里得学习笔记

温馨提示:本文推式子比较多,建议跟着文章自己推一推。

扩展欧几里得是什么

扩展欧几里得(exgcd)是一个可以用来求 ax+by=cc%gcd(a,b)=0,否则无解)的解的算法

求解 ax+by=gcd(a,b)

首先,如果 b=0 的话,gcd(a,b)=a,则解为 {x=1y=0

设此方程的解为 {x=x0y=y0

那么我们需要做的就是将 ax0+by0=gcd(a,b) 转化为 b=0 的格式,这就要用到辗转相除法了。

设另一个方程:bx1+(a%b)y1=gcd(b,a%b)

a1=b,b1=a%b

则该方程转化为 a1x1+b1y1=gcd(a1,b1)

我们会发现它和原方程的格式是一样的,而且根据欧几里得原理,它可以一直递推到 anxn+bnyn=gcd(an,bn) 使得 bn=0,就可以求得解 {xn=1yn=0

那假设我们已经求得了该结果,那如何推导出 x0y0 呢?

我们首先研究如何从 x1y1 推导出一组合法的 x0y0,其他的就同理了

因为

{bx1+(a%b)y1=gcd(b,a%b)ax0+by0=gcd(a,b)

且根据欧几里得定理,gcd(a,b)=gcd(b,a%b)

所以

ax0+by0=bx1+(a%b)y1

a%b=aabb(模运算的意义)

所以

ax0+by0=bx1+(aabb)y1=bx1+ay1abby1=b(x1aby1)+ay1=ay1+b(x1aby1){x0=y1y0=x1aby1

这样,我们就由 x1y1 推导出了 x0y0,其他同理

于是乎:

struct node
{
	int x,y;
};
node exgcd(int a,int b)
{
	if(b==0)
	{
		node tmp;
		tmp.x=1,tmp.y=0;
		return tmp;
	}
	node tmp=exgcd(b,a%b);//递归求出x_(k+1)和y_(k+1)
	node ans;
	ans.x=tmp.y,ans.y=(tmp.x)-a/b*(tmp.y);//推导出x_k和y_k
	return ans;
}

这样,我们就求出了 ax+by=gcd(a,b) 的一组解

ax+by=c 的一组解 {x=xtmpy=ytmp

我们已经求出了 ax+by=gcd(a,b) 的一组解 {x=x0y=y0

那么我们就可以知道 akx0+bky0=kgcd(a,b)

又因为要求 cgcd(a,b) 的倍数(否则无解)

所以 k=cgcd(a,b)

所以很简单:

{xtmp=kx0=cgcd(a,b)x0ytmp=ky0=cgcd(a,b)y0

3.ax+by=c 的所有解 {x=xansy=yans

我们已经求出了 ax+by=c 的一组解 {x=xtmpy=ytmp

axtmp+bytmp=c

将它加上再减去 abgcd(a,b),得到

axtmp+abgcd(a,b)+bytmpabgcd(a,b)=ca(xtmp+bgcd(a,b))+b(ytmpagcd(a,b))=c

xtmp 上减,在 ytmp 上加也同理

所以 {x=xtmp±bgcd(a,b)y=ytmpagcd(a,b) 也是一组解

这个变换进行多次,即可得到

{xans=xtmp+t×bgcd(a,b)yans=ytmpt×agcd(a,b)

xy 各自的最小正整数解

x 的最小正整数解为例:

求出任意一组解 {x=xtmpy=ytmp

因为将 xtmp 加或减 bgcd(a,b) 也成立,所以可设 d=bgcd(a,b)(注意这里分子是 b

xmin=(xtmp%d+d)%d(因为 xtmp 有可能是负数)

同理对于 y,设 d=agcd(a,b)(注意这里分子是 a

ymin=(ytmp%d+d)%d

完结撒花

至此,你已经学完了扩展欧几里得的基础用法,如有不懂的地方,建议对照着文章自己推一推,悟一悟。

做个题练习一下吧:洛谷 P5656 【模板】二元一次不定方程 (exgcd)

posted @   曹轩鸣  阅读(12)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起