扩展欧几里得算法 算法训练

本文深入探讨了扩展欧几里得算法,从基本的欧几里得算法出发,阐述了如何找到线性同余方程ax+by=c的解,并通过实例解释了算法过程。同时,介绍了当c为gcd(a, b)的倍数时如何求解,以及如何通过扩展算法求得其他解的方法。此外,讨论了扩展欧几里得算法在求解不定方程和模线性方程等领域的应用。
摘要由CSDN通过智能技术生成

今天刚学扩展欧几里得算法,打算趁热写篇博客回顾一下,顺便防止以后自己忘记了。
话不多说。

首先请出欧几里得算法,还是非常简洁明了的。

int gcd(int a, int b)
{
	if (b == 0)
	{
		return a;
    }
	return gcd(b, a % b);
}

顺便提一句,欧几里得算法不需要考虑a和b的大小,因为假如a<b,会return (b,a%b);a%b=a,相当于交换了一次,因此不需要考虑大小。(以前老是忘记,一直考虑大小问题)

然后就要写扩展欧几里得算法了,先整个问题引出扩展欧几里得算法。

假如我们要求ax+by=c的一组解,也就是求x,y,这时候我们就需要用到扩展欧几里得算法了。
首先我们还需要一个定理:

ax+by=c。c必须为gcd(a,b)的倍数。(证明我还是不写了,不太会,而且我觉得下面的过程看完了也大概能明白为什么c必须是gcd的倍数了)

接着举个例子好了;
a=78,b=51,c=3.
根据gcd可以推出过程为:

78 51 | 51 * 1+27=78
51 27 | 27 * 1+24=51
27 24 | 24 * 1+3=27
24 3 | 3 * 8=24
3 0 |
至此我们可以算出gcd(78,51)=3;
这时候有人就问了,这有什么意义吗?跟c也没任何关系啊,这时候我们就要引出他们之间的关系了.

根据241+3=27。我们可以得到3=27-24 * 1,这说明27和24就是3的一个线性组合。
根据27
1+24=51。我们可以得到3=27-(51-27)*1=(-51)+27 * 2,这说明51和27也是3的一个线性组合。
如下,我们可以这样的式子。
3=27-24 * 1=(-51)+27 * 2=78 * 2-51 * 3。
实际上,最后的2和(-3)正是我们需要的一组解。那我们应该怎么将这个过程表示出来呢?
就是通过求bx0+(a mod b)*y0=c关联ax+by=c。
a mod b=a-b * (a/b)。于是我们可以得到这样一个方程组。
x=y0。
y=x0-(a/b) y0是不是有辗转相除法内味了。

于是乎我们就可以引出扩展欧几里得算法了。

int exgcd(int a, int b, int x, int y)
{
	if (b == 0)
	{
		x = 1; y = 0;
		return a;
    }
	int d = exgcd(b, a % b, x, y);
	int x0, y0;
	x0 = x;
	y0 = y;
	x = y0;
	y = x0 - (a / b) * y0;
		return d;
}

当然我们还可以进一步化简代码,利用一下c++的引用。

下面放出代码:

int exgcd(int a, int b, int& x, int& y)
{
	if (b == 0)
	{
		x = 1; y = 0;
		return a;
    }
	int d = exgcd(b, a % b, y, x);//这里x和y交换了一下位置,需要注意一下
		y -= (a / b) * x;
		return d;
}

其实和上面差不多,但是稍微精简了一下,如果看不懂意思,可以看我的下面的分析:
根据d=exgcd(b,a%b,y,x)可以得到y=x0,x=y0。因此实际上x已经等于y0了,之后就是y-=(a/b)* x;实际上等于y=y-(a/b) * x;此时的y=x0,x=y0,与上面的y=x0-(a/b)*y0实际上是完全一样的。

最后还有另一个问题,就是我们这里讨论的c正好是78和51的最大公因数,假如不是最大公因数,而是最大公因数的倍数,那该咋办呢?

那我们只需要把ax+by=k * gcd(a/b);改成a * k*x‘+b * k * y’=k * gcd(a/b)即可。

这样我们就成功求出了一组解。

那我们还想要其他的解,要咋办呢?
我们设x1=x+f以及y1我们可以得到a * (x1-f)+by=c。然后将(x1-f)从括号里拆出来最后再合并可以得到ax1+b(y-af/b)=c。
因此我们可以得到一个方程组
x1=x+f
y1=y-a*f/b

我们还需要保证f和af/b为整数,并且后者要等于a’f/b’,其中a’=a/gcd(a,b),b’=b/gcd(a,b)。因为a’与b’互质,因此f=k * b’。
最后得到
xk=x+k * b/gcd(a,b)
yk=y-k * a/gcd(a,b)
的方程组。

怎么说呢(其实斜体这一小段是从我学习的那个博客那边照搬过来的,因为我还不是特别能理解)

至此我们通解也可以求出来了,最后想说一下扩展欧几里得算法的应用,但我现在也没刷过这种题,只能先引用一下别人认为的应用有哪些了,之后有时间我回来补一下。
1求解不定方程

2求解模线性方程(线性同余方程)

3求解模的逆元

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值