1.拓展欧几里得算法介绍
我们知道欧几里得算法是用来求解最大公约数的,那么拓展欧几里得算法是用来干嘛的呢?
先给个题:
给定,求一组
,使得
你可能很好奇这有什么用呢?
别急,先听我把这个介绍完,然后我会介绍它的两个应用,分别是解线性方程与解一次同余方程
。
回到,我们需要知道一个定理:
裴蜀定理
对于任意正整数a,b;一定存在非零整数x,y,使得:
ax + by = gcd(a,b)
其中gcd(a,b)指a和b的最大公约数
拓展欧几里得算法的作用就是找出满足裴蜀定理的一组 x 和 y。
下面我将介绍计算的流程,首先我先剧透一下,这与拓展欧几里得算法与欧几里得算法类似,都是一个递归程序。使用子递归程序的结果来更新本程序的返回值。
算法如下:
当时,
(是不是感觉很像欧几里得算法的判断条件)
当时, 这里能体现出为什么这个算法叫拓展欧几里得算法,因为要用到欧几里得算法的一个结论
。
我们使用裴蜀定理可以知道:
现在我们来看看这个到底与
有什么关系,如果我们能建立这个关系,我们就能够写成一个递归程序。
故而我们有
所以,直接上代码(使用引用传递值可能有点绕)
int exgcd(int a, int b, int &x, int &y)
{
if (!b)
{
x = 1; y = 0;
return a;
}
int d = exgcd(b, a % b, y, x); //这句话的意思是,用当前y来保存子递归程序的x',x来保存y'
y -= (a/b) * x;// 这里是因为刚刚推出的式子 y = x' - (a/b) * y' = y - (a/b) * x;
return d; //返回值不用管
}
2.应用一:求解一般方程![ax + by = c](https://latex.csdn.net/eq?ax%20+%20by%20%3D%20c)
刚刚我们知道有整数解,而且解也能算出来。
那么显然当是
的倍数时,这个方程有解。
令
我们有那么特殊解。
而通解 = 特解 + 齐次解
方程的解是
是整数。
所以通解是
3. 应用二:解一次同余方程![ax\equiv b(mod \ m)](https://latex.csdn.net/eq?ax%5Cequiv%20b%28mod%20%5C%20m%29)
乍一看没法没法用
但是别急, 我们可以设, 那么我们就有
,
是不是一模一样啊。
有解条件是,有解的话直接用上面的方法求就可以了。
特别地,如果你还记得上一篇博客里面的费马小定理,当且
与
互质的时候,
是
的乘法逆元,即
,用快速幂计算就可以啦。
对自己有信心的可以去尝试P1082 [NOIP2012 提高组] 同余方程