zoukankan      html  css  js  c++  java
  • 欧几里得和扩展欧几里得

    别人总结的,很详细,http://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html

    欧几里得算法,就是人们常说的辗转相除法,比较好理解,主要作用是求两个数最大公约数,最小公倍数也可方便的求出

    1 int gcd(int a,int b)
    2 {
    3     return b==0?a:gcd(b,a%b);
    4 }
    View Cod

    扩展欧几里得就非常神奇了,主要作用是解不定方程, 即  a * x + b * y = c ,我们都知道可以有解,但不是唯一解

    用 exgcd 可以很快求出  a * x + b * y = gcd(a,b) 的一个特解。如果  gcd(a,b) | c   即,有整数解,否则无

    假如求出特解  x0 ,y0  那么通解 a * x + b * y = gcd(a,b)  为

    x = x0 + b / gcd(a,b) * t   ( t 为任意整数 )

    y = y0 - a / gcd(a,b) * t   ( t 同上 )

    保证了式子恒等,所以是通解,假如要求 x 的最小非负整数解即 ,设 m = b / gcd(a,b)  ,x = (x0 % m + m)%m  (前提要 b / gcd(a,b)为正)

    再回到 a * x + b * y = c 的特解,设, k = c / gcd (a,b)

    那么特解 x1 = k * x0  ,  y1 = k * x0

    式子变为 a * x1 + b * y1 = z   ,咋一看通解为  x = x1 + b * t    y = x2 - a * t

    其实不对,先将两边同除 gcd(a,b)  得  a1 * x1  + b1 * y1 =  k 

    容易看出, a * x + b * y = c 通解为

    x = x0*k + b/gcd(a,b) * t 

    y = y0*k - a/gcd(a,b) * t (t为任意整数)

    因为 b1 <= b 所以对 b1 取模一定小于等于 b,

    同样方法取最小非负解

    扩展欧几里得还可以很方便的求乘法逆元 a * x == 1 (mod m) x 即为 a 的乘法逆元

    可以变形为 a * x + m * y == 1 (mod m)

    exgcd(a,m,x,y) 后,x 可能是负数,同上方法处理 (x % m/gcd + m/gcd) % m/gcd 

     1 int exgcd(int a,int b,int &x,int &y)
     2 {
     3     if (b==0)
     4     {
     5         x=1;
     6         y=0;
     7         return a;
     8     }
     9     int r = gcd(b,a%b,y,x);
    10     y-=(a/b)*x;
    11     return r;
    12 }
    View Code
  • 相关阅读:
    继承
    面向对象_封装练习
    ajax分页与组合查询配合使用
    Linq的分页与组合查询的配合使用
    发送邮件和数据导出
    GridView的使用
    母版页的使用
    DIV+CSS命名规范
    Ajax基础
    jQuery动画效果
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/7240023.html
Copyright © 2011-2022 走看看