zoukankan      html  css  js  c++  java
  • 扩展欧几里得学习小记

    扩展欧几里得是干什么的?给定两个数a,b,设Gcd(a,b)=d(d是a,b的最大公约数),则存在整数x,y,使得x*a+y*b=d。

    扩展欧几里得可以求出x,y。怎么求呢?我们知道,Gcd(a,b)=Gcd(b,a%b),而我们也就是运用这个东西来求a和b的最大公约数的。

    因此,设bx+(a%b)y=d,即bx+(a-a/b*b)y=d,所以:ay+b*(x-a/b*y)=d。因此我们可用下面的代码解决:

     

    int64 exGcd(int64 a,int64 b,int64 &x,int64 &y)
    {
        int64 r,t;
        if(b==0)
       {
           x=1;
           y=0;
           return a;
       }
       r=exGcd(b,a%b,x,y);
       t=x;
       x=y;
       y=t-a/b*y;
       return r;

    }

    这个程序返回值为Gcd(a,b),ax+by=Gcd(a,b),其中x,y分别存在x,y中。

    当然,如果给出的是求ax+by=c,这时当且仅当Gcd(a,b)可以整除c时x,y有整数解。这个很好证明,设Gcd(a,b)=d,那么a=d*k1,b=d*k2,所以ax+by=d*(k1*x+k2*y),即ax+by必为d的倍数,所以c必为d的倍数,即d必能整除c。这样的话,先求ax+by=d的一组解x0,y0,设k=c/d,则k*x0,k*y0就是一组解。

     

    另外,扩展欧几里得可以求乘法逆元。乘法逆元的意思就是对于a,p,若存在b使得ab%p=1,则称b为a对p的乘法逆元。那么这个b有什么意思呢?对于一个数x,x/a%p=x*b%p(a可以整除x)。这样的话,就可以将除法变为乘法,那么为什么上式成立呢?设x=k*a,则x/a%p=k%p=(k%p)*(ab%p)=(k*a*b)%p=x*b%p。那么怎么求b呢?ab%p=1,我们可得ab=kp+1(k为某个整数),即ab-kp=1,令x=b,y=-k,则我们求出ax+py=1的一组解x,y即可。这个式子有解的充要条件是Gcd(a,p)=1.

    证明如下:

    (1)若Gcd(a,p)=1,有欧拉定理,设Ψ(x)表示x的欧拉函数(Ψ(x)是一个数,是[1,x-1]中与x互质的数的个数),(a^Ψ(x))%p=1,所以b=a^(Ψ(x)-1)就是一个答案;

    (2)若ab%p=1,则ab=kp+1,ab-kp=1,设Gcd(a,p)=d,则d必能整除1,所以d只能是1。

    这样的话就能用上面的代码求了。。。

  • 相关阅读:
    WebUploader在IE9中文件选择按钮点击没反应
    nagios二次开发(四)---nagios监控原理和nagios架构简介
    nagios二次开发(三)---nagiosql架构简介
    nagios二次开发(二)---nagios和nagiosql合并与取舍
    Icinga快速安装与配置
    shell-自动更改LINUX服务器IP
    nginx环境下配置nagios-关于nagios配置文件nginx.conf
    nginx环境下配置nagiosQL-关于nagiosql配置文件
    nginx环境下配置nagios-关于start_perl_cgi.sh
    Scala学习(八)---Scala继承
  • 原文地址:https://www.cnblogs.com/jianglangcaijin/p/3446822.html
Copyright © 2011-2022 走看看