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

    2016.1.25

    (未更新完)

    一、欧几里得算法(辗转相除法)

    1、用途:快速计算两个数的最大公约数。

    2、精髓:gcd(a,b)=gcd(b,a%b)

    3、证明:设r=a mod b,则我们要证明的是gcd(a,b)=gcd(b,r)

                 设gcd(a,b)=c,则a=mc,b=nc,且m,n互质。那么r=a-kb=(m-kn)c,所以c也是r的因数。

                 若gcd(b,r)>c,则设为d,则有b=m1*d,r=n1*d,所以a=(m1+n1)*d,则d为a的因数,所以gcd(a,b)=d,与题设不符。

                 所以gcd(a,b)=gcd(b,r)

    4、时间复杂度:显然经过两次递归后第一个参数至少减小一半

                          所以时间复杂度粗略为O(log max(a,b))

    5、经典例题:线段上格点的个数

     

    二、扩展欧几里得算法:

    1、用途:快速求整数x,y使得ax+by=gcd(a,b)

    2、精髓代码:

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

         3、证明:由于gcd(a,b)=gcd(b,a%b)

                      所以b*x1 + (a%b)*y1 = gcd(a,b)

                      a%b = a - (a/b)*b

                      所以gcd(a,b) = b*x1 + (a-(a/b)*b)*y1

                                        = b*x1 + a*y1 – (a/b)*b*y1

                                        = a*y1 + b*(x1 – a/b*y1)

                      对于我们所求的x,y使得ax+by=gcd(a,b)

                      则有  x = y1

                      y = x1 – a/b*y1

                      证毕

                      至于终止条件,因为当欧几里得算法终止时a=gcd,b=0,则当x=1,y=0时,必使目标公式成立。

                      另外关于ax+by=c的充要条件为什么是c=gcd(a,b),可以自行百度一下裴蜀定理。

         4、时间复杂度:与欧几里得算法一致

         5、经典例题:双六

  • 相关阅读:
    canvas上的像素操作(图像复制,细调)
    AMD、CMD、CommonJS 和 ES6 模块化规范
    JS垃圾回收
    函数式编程中如何处理副作用?
    vue中的$on,$emit,$once,$off源码实现
    重新学习react生命周期
    keep alive实现原理
    读取 url 参数方法
    使用Bootstratp Blazor +EF Codefirst 愉快的增删改查!
    记录一下爬取微信小程序视频的过程!
  • 原文地址:https://www.cnblogs.com/16er/p/5158332.html
Copyright © 2011-2022 走看看