拓展欧几里得与逆元

来源:互联网 发布:mac截屏键 编辑:程序博客网 时间:2024/06/06 02:29

拓展欧几里得与逆元


前言

作为信息组众多神犇Oier中唯一的蒟蒻Oier,我终于学到了逆元(也就是神犇们看不起的很水很简单的算法),但我兴奋了一阵以后,发现了一个无奈的事实,那就是看不懂,因为神犇们的神奇思想十分的跳跃,并非我等凡人小辈可以解读的,无奈之下,只能硬着头皮慢慢读下去.皇天不负有心人,我终于混到了一个半懂不懂的水平,为了防止大家重蹈我被%神犇%的摧残经历,就打算写一篇平易近人的文章.


欧几里得算法

先来讲一下欧几里得算法(gcd)
我们定义a,b(a>b)两数的最大公约数为gcd(a,b).则 a,b一定为gcd(a,b)的倍数
我们记做:

a=x1gcd(a,b)

b=x2gcd(a,b)


c=ab=(x1nx2)gcd(a,b)(x1nx20)

则c也为gcd(a,b)倍数且c<b,所以gcd(a,b)=gcd(b,c),可以以此性质递归求出gcd(a,b)的值.核心代码如下:

    int gcd ( int a , int b) { return a % b ? gcd( b , a % b ) : b ; }

拓展欧几里得

拓展欧几里得(exgcd),是以欧几里得递归相同的方式求解乘法逆元,同余方程的一种算法,同余方程一般写作如下形式.

axgcd(a,b)mod b


axby=gcd(a,b)

因gcd(a,b)=gcd(a,-b),所以原式等价变化为:
ax+by=gcd(a,b)

将gcd(a,b)除过来,可得:
agcd(a,b)x+bgcd(a,b)y=1

此时x,y系数互质,即转化成,一般同余方程形式:
ax1(mod b)

ax+by=1

基于我的理解,我觉得用ax1(mod b)更好理解,故,接下来用此式推演.


总结一下,此式同余方程为:

ax1(mod b)

我们令: k=ax % b
我们假设一组数据:a=3,b=10.
x=1时,k=a1 % b=3
x=2时,k=a2 % b=6
x=3时,k=a3 % b=(9 % b)=9
x=4时,k=a4 % b=(12 % b)=2
x=5时,k=a5 % b=(15 % b)=5
x=6时,k=a6 % b=(18 % b)=8
x=7时,k=a7 % b=(21 % b)=1

当我们提出里边几个式子,即可看出规律:

x=1时,k=a1 % b=(3  % b)=3
x=4时,k=a4 % b=(12 % b)=2
x=7时,k=a7 % b=(21 % b)=1
x每增加floor(ba)时,k减小a % b)
所以x增加floor(ba)次数为:

ay1(a % b)y2=1

y2的最小解.
即为同余方程
(a % b)x1(mod a)

的最小解.
所以可以依次性质递归下去求解同余方程.
我们令形如:
ax1(mod b)

的最小解为 exgcd(a,b);
exgcd(a,b)=aexgcd(b,a%b)(ab)

即可用此算法求解同余方程,代码如下:

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