zoukankan      html  css  js  c++  java
  • 扩展欧几里德算法

    void gcd(int a,int b,int &d,int &x,int &y)
    {
        if(!b)
        {
            d=a;
            x=1;
            y=0;
        }
        else
        {
            gcd(b,a%b,d,y,x);
            y-=x*(a/b);
        }
    }

    扩展欧几里德算法的应用主要有以下三方面:

    (1)求解不定方程;

    (2)求解模线性方程(线性同余方程);

    (3)求解模的逆元;

    (1)使用扩展欧几里德算法解决不定方程的办法:

      对于不定整数方程pa+qb=c,若 c mod Gcd(p, q)=0,则该方程存在整数解,否则不存在整数解。
      上面已经列出找一个整数解的方法,在找到p * a+q * b = Gcd(p, q)的一组解p0,q0后,p * a+q * b = Gcd(p, q)的其他整数解满足:
      p = p0 + b/Gcd(p, q) * t 
      q = q0 - a/Gcd(p, q) * t(其中t为任意整数)
      至于pa+qb=c的整数解,只需将p * a+q * b = Gcd(p, q)的每个解乘上 c/Gcd(p, q) 即可。

      在找到p * a+q * b = Gcd(a, b)的一组解p0,q0后,应该是得到p * a+q * b = c的一组解p1 = p0*(c/Gcd(a,b)),q1 = q0*(c/Gcd(a,b)),

      p * a+q * b = c的其他整数解满足:

      p = p1 + b/Gcd(a, b) * t
      q = q1 - a/Gcd(a, b) * t(其中t为任意整数)
      p 、q就是p * a+q * b = c的所有整数解。
    用扩展欧几里得算法解不定方程ax+by=c;
    bool judge(int a,int b,int c,int &x,int &y)
    {
        int d=gcd(a,b,x,y);
        if(c%d)
            return false;
        int k=c/d;
        x*=k; y*=k;    //求得的只是其中一组解
        return true;
    }

    (2)用扩展欧几里德算法求解模线性方程的方法:

        同余方程 ax≡b (mod n)对于未知数 x 有解,当且仅当 gcd(a,n) | b。且方程有解时,方程有 gcd(a,n) 个解。

        求解方程 ax≡b (mod n) 相当于求解方程 ax+ ny= b, (x, y为整数)

        设 d= gcd(a,n),假如整数 x 和 y,满足 d= ax+ ny(用扩展欧几里德得出)。如果 d| b,则方程

        a* x0+ n* y0= d, 方程两边乘以 b/ d,(因为 d|b,所以能够整除),得到 a* x0* b/ d+ n* y0* b/ d= b。
        所以 x= x0* b/ d,y= y0* b/ d 为 ax+ ny= b 的一个解,所以 x= x0* b/ d 为 ax= b (mod n ) 的解。

        ax≡b (mod n)的一个解为 x0= x* (b/ d ) mod n,且方程的 d 个解分别为 xi= (x0+ i* (n/ d ))mod n {i= 0... d-1}。

        设ans=x*(b/d),s=n/d;

        方程ax≡b (mod n)的最小整数解为:(ans%s+s)%s;

    a*dx就是a的倍数,同时也是n的倍数,即a*dx是a 和 n的公倍数.为了求出dx,我们应该求出a 和 n的最小公倍数,此时对应的dx是最小的.

    设a 和 n的最大公约数为d,那么a 和 n 的最小公倍数为(a*n)/d.

    即a*dx = a*n/d;

    所以dx = n/d.

    因此解之间的间隔就求出来了.

    bool modular_linear_equation(int a,int b,int n)
    {
        int x,y,x0,i;
        int d=gcd(a,n,x,y);
        if(b%d)
            return false;
        x0=x*(b/d)%n;   //特解
        for(i=1;i<d;i++)
            printf("%d
    ",(x0+i*(n/d))%n);
        return true;
    }

    (3)用欧几里德算法求模的逆元:

           同余方程ax≡b (mod n),如果 gcd(a,n)== 1,则方程只有唯一解。

          在这种情况下,如果 b== 1,同余方程就是 ax=1 (mod n ),gcd(a,n)= 1。

          这时称求出的 x 为 a 的对模 n 乘法的逆元。

          对于同余方程 ax= 1(mod n ), gcd(a,n)= 1 的求解就是求解方程

          ax+ ny= 1,x, y 为整数。这个可用扩展欧几里德算法求出,原同余方程的唯一解就是用扩展欧几里德算法得出的 x 。

  • 相关阅读:
    自学it18大数据笔记-第三阶段Scala-day03——会持续更新……
    自学it18大数据笔记-第三阶段Scala-day01+~day02——会持续更新……
    自学it18掌大数据笔记-第三阶段Scala-day00-day01——会持续更新……
    自学it18大数据笔记-第三阶段Storm-day5——会持续更新……
    自学it18大数据笔记-第三阶段Storm-day4——会持续更新……
    自学it18大数据笔记-第三阶段Storm-day2-day3——会持续更新……
    自学it18大数据笔记-第三阶段Storm-day1——会持续更新……
    自学it18大数据笔记-第二阶段Sqoop-day1——会持续更新……
    自学it18大数据笔记-第二阶段Pig-day1——会持续更新……
    自学it18大数据笔记-第二阶段Kafka-day2——会持续更新……
  • 原文地址:https://www.cnblogs.com/d-e-v-i-l/p/4741787.html
Copyright © 2011-2022 走看看