浅谈拓展欧几里得算法(辗转相除法)

前言

前天讲了一堆的数论,还没什么时间整理,拓欧我也只是第一次接触(果然还是太蒟),搞了半个晚上才弄懂。避免遗忘或弄丢,写篇博文。

拓展欧几里得算法

了解一下:扩展欧几里得算法,简称 exgcd,一般用来求解不定方程,求解线性同余方程,求解模的逆元等

 

引理:存在 x , y 使得 gcd(a,b)=ax+by,求 x,y

证明:

part 1:

(1)由gcd(a,b)= gcd(b,a mod b)             //辗转相除法

         得ax+by = by+(a mod b)*y

(2)bx+(a mod b)*y = bx+(a - (a div b)*b)*y     //(a - (a div b)*b)相当于a mod b,总数-最大倍数=余数

                                        = bx+ay-(a div b)*b*y            //乘法分配律

                                        =ay + b*(x-a div b*y)             //乘法结合律,提取公因数b

(3)exgcd(ax+by)= exgcd(ay+b*(x-a div b*y))

part 2:

终止:当 b=0 时,ax = gcd(a,b),x=1,y=0

           exgcd 的返回值就是gcd(a,b)

part 3:

那么怎么求其他解:

任取一组解(x2,y2),则ax1 + by1 = ax2 + by2(都等于gcd(a,b) = d),
变形得a(x1-x2)= b(y2-y1)
两边同时除以gcd(a,b)(a=a div d ,b=b div d)
此时a与b互素,因此(x1-x2)一定是b的整数倍,则y2-y1=ka,k为正整数
有了这个结论,很容易求出ax+by=-c

part 4:

ax+by=c 无整数解的情况:c不能被gcd(a,b)整除。(即c不是gcd(a,b)的倍数)

理由:因为 ax 与 by 均是gcd(a,b)的倍数,所以其和 ax+by 也是gcd(a,b)的倍数

           因为 gcd(a,b) | ax , gcd(a,b) | by

           所以 gcd(a,b) | ax+by

CODE

ll exgcd(ll a,ll b,ll x,ll y)
{
    if (b==0)
    {
        x = 1;
        y = 0;
        return a;
    }//终止
    ll d = exgcd(b,a mod b,x,y);
    ll t = x;//先存好现在的x
    x = y;
    y = t-(a div b)*y;
    return d;
}

应用

输入方正整数a,b,n,解方程ax≡b(mod n),也就是求解ax和b关于n同余

由同余定理,ax≡b(mod n)的充要条件是ax-b是n的整数倍

那么我们设这个倍数为y ,则得到 ax-ny=b,可以用上述算法解

当a和n互素的时候,此方程有为一解

你可能感兴趣的:(知识点,算法)