扩展欧几里得算法

拓展欧几里得算法

先来看看一个重要的基本定理

裴蜀定理

对于整数a,b,他们关于x,y的线性不定方程(ax+by=d),设(gcd(a,b)=g),则可证明(g|d),换句话说,就是g是a,b的最小线性组合

证明:

(ax+by=d)(g=gcd(a,b)),设(ax+by)的最小值为s,

(ecause) (g|a,g|b)

( herefore) (g|d),(g|s)

(q=[frac{a}{s}].则r= amod s=a-q*s=a-q*(ax+by)=a(1-qx)+b(-qy))

可见r也是x,y的线性组合,又r是s的余数,(rin [0,s-1]),又s是最小线性组合,( herefore r=0)

推出(s|a),同理有(s|b),则(s|g),又已经有(g|s),所以(g=s)。可知g是ax+by的最小线性组合。

推论:

a和b互质的充要条件是存在x,y使(ax+by=1),因为由上面的证明结论知道d(这里是1)一定是gcd(a,b)的倍数。

其实还可以推广到一堆数互质(这些数的gcd为1)的情况。

拓展欧几里得

我们知道,一般的 欧几里得算法是来求两个数的最大公因数的,但是拓展欧几里得可以走得更远,也就是说,它不仅仅求一个gcd,而是可以求出一些额外的东西。前面的定理说了a,b线性组合最小是(gcd(a,b)),我们就可以求出(ax+by=gcd(a,b))对应的x,y出来。

怎么求呢?我们已经知道当欧几里得算法递归到终点时,gcd(a,b)中的b已经是零,也就是说,这个时候(a*1+b*0=a),x=1,y=0,我们就可以在这时反推上去求解最终的x,y

现在是递归返回过程的某一步,我们已经求得了b和a%b的gcd,还有此时的x1,y1,就是说(b*x1+a\%b*y1=gcd),要怎么求a,b的x,y呢?

我们知道(a\%b=a-[frac{a}{b}]*b)(gcd=b*x1+(a-[frac{a}{b}]*b)*y1=b*x1+a*y1-[frac{a}{b}]*y1*b=a*y1+(x1-[frac{a}{b}]*y1)*b=a*x+b*y)

可以看出(x=y1,y=x1-[frac{a}{b}]*b).递归返回时即可更新掉x,y的值返回即可。

代码:

int ex_gcd(int a,int b,int& x,int& y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }
    int ans = ex_gcd(b,a%b,x,y);
    int tmp = x;
    x = y;
    y = tmp-a/b*y;
    return ans;
}

拓展欧几里得求逆元

什么是逆元?(a*xequiv{1}mod m),这里(x)就是a的逆元。逆元有什么用呢?*如果我们要求(a/b mod m)的值,而a,b很大,设b的逆元为x,这个时候注意到((a/b)*x*b=(a/b)mod m=a*xmod m)巧妙地把出发转换成了乘法。

为什没求逆元跟欧几里得算法联系起来了呢?根据上面裴蜀定理,我们知道gcd是a,b两个数线性组合的最小值,其他组合值都是gcd的倍数,当gcd为1时,a,b互质,满足(ax+by=1),移项得(ax=-by+1),即(axequiv1mod b),此时的x就是逆元。实际上线性不定方程组有无穷多解,这里只求正的最小的逆元。

代码

int cal(int a,int m)
{
    int x,y;
    int gcd = ex_gcd(a,m,x,y);
    //cout << "a " << a << " m " << m << " x " << x << " y " << y << endl;
    if(1%gcd!=0) return -1;
    x*=1/gcd;
    m = abs(m);
    int ans = x%m;
    if(ans<=0) ans += m;
    return ans;
}

这里1%gcd是看gcd是不是1,前面说了,d(这里是1)应该是gcd的倍数,而且不互质的两个数没有逆元。(x*=1/gcd)实际上更一般的写为(x*=d/gcd),也就是求解一般不定方程(ax+by=d)的解,因为d是gcd的倍数,我们就把倍数乘上去解得(x'=x*(d/gcd))。m是负数的话,我们取|m|,如果求出来x是负数,就x%|m|,结果再加上|m|即可。(因为有无穷个解,通解为(x+m*t)

参考文章

zhj5chengfeng,扩展欧几里德算法详解,https://blog.csdn.net/zhjchengfeng5/article/details/7786595

leader_one,欧几里得算法/扩展欧几里得算法,https://blog.csdn.net/leader_one/article/details/75222771

Jollwish,扩展欧几里得算法,https://wenku.baidu.com/view/a75fdfd376a20029bd642de5.html

原文地址:https://www.cnblogs.com/zhanhonhao/p/11329772.html