• 欧几里得,扩展欧几里得相关


    欧几里得(gcd)

    欧几里得算法通过辗转相除法求得x,y的最小公约数

     
    /* 迭代法(递推法):欧几里得算法,计算最大公约数 */
    int gcd(int n, int m)
    {
        while(m>0)//余数大于零
        {
            int c = n % m;
            n = m;
            m = c;
        }
        return n;//输出最后一个整除的数
    }

    扩展欧几里得

    扩展欧几里得算法是欧几里得算法(又叫辗转相除法)的扩展。除了计算a、b两个整数的最大公约数,此算法还能找到整数x、y(其中一个很可能是负数)。通常谈到最大公因子时, 我们都会提到一个非常基本的事实: 给予二整数 a 与 b, 必存在有整数 x 与 y 使得ax + by = gcd(a,b)。有两个数a,b,对它们进行辗转相除法,可得它们的最大公约数–这是众所周知的。然后,收集辗转相除法中产生的式子,倒回去,可以得到ax+by=gcd(a,b)的整数解。

    long long exgcd(long long a,long long b,long long &x,long long &y)
    {
    if (b==0) { x=1,y=0; return a; }
    long long d=exgcd(b,a%b,x,y);
    long long tmp=x;
    x=y;
    y=tmp-a/b*y;
    return d;
    }

    通过扩展欧几里得求逆元

    (A*X)%MOD=1;那么肯定存在k使得

    A*X=k*MOD+1;

    移项可得:A*X-k*MOD=1;

    所以,当A和MOD互素时,就可以写成

    A*X-k*MOD=gcd(A,MOD);

    如果把A看做a,MOD看做b,X看做x,-k看做y的话,则上式可化为:

    ax+by=gcd(a,b);

    这样就可以用扩展欧几里得算法求出来x了,也就是我们要找的逆元。

    int mod_reverse(int a,int n)//ax=1(mod n) 求a的逆元x 
    {
        int d,x,y;
        d=ex_gcd(a,n,x,y);
        if(d==1)
            return (x%n+n)%n;
        else
            return -1;
    }

    求解ax=c(mod b)(也就是ax+by=c(同上逆元的变化方式))的x的最小整数解

    int cal(int a,int b,int c)
    {
        int x,y;
        int gcd=(a,b,x,y);
        if(c%gcd!=0)
            return -1;//代表无解 
        //  ax0+by0=gcd(a,b)                                方程一 
        //同时乘以c/gcd(a,b)得   
        // (a*c/gcd(a,b))*x0+(b*c/gcd(a,b))*y0=c;
        // 令 x1=c/gcd(a,b)*x0  y1=c/gcd(a,b)*y0;
        // 则可得 ax1+by1=c                                 方程二 
        // 这时得出方程的一个解   x1=x0*c/gcd(a,b)     y1=y0*c/gcd(a,b)  
        x*=c/gcd; //将 方程一的一个特解转化成方程2的一个特解 
        //套用上文的公式可得对方程二
        // b'=b/gcd(a,b);
        b/=gcd;   
        if(b<0)//处理小于0的特殊情况 
            b=-b;
        //对特解x  +- kb'  找到最小整数解
        //设x=kb'+r
        //那么我们想要求的整数解就是r
        //直接取模运算即可 
        int ans=x%b; 
        //把负数的r转化成正数的 
        if(ans<=0)
            ans+=b;
        return ans;
    }

      

  • 相关阅读:
    java 集合list遍历时删除元素
    循环中的continue功能
    sql中的!=判断的注意事项
    oracle中时间处理
    judge return character
    ashamed
    char and number transform
    将十进制转化为二进制
    算法和程序
    输入分子和分母,打印出前1000位小数
  • 原文地址:https://www.cnblogs.com/wjune-0405/p/11726763.html
Copyright © 2020-2023  润新知