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

    欧几里德算法又称辗转相除法,用于计算两个整数a,b的最大公约数。

    基本算法:设a=qb+r。当中a,b。q,r都是整数。则gcd(a,b)=gcd(b,r)。即gcd(a,b)=gcd(b,a%b)。

    递归代码

    __int64 gcd(__int64 a,__int64 b)
    {
        return b==0?a:gcd(b,a%b);
    }

    扩展欧几里得

    基本算法对于不全然为 0 的非负整数 a,b。gcd(a。b)表示 a,b 的最大公约数,

              必定存在整数对 x。y ,使得 gcd(a,b)=ax+by。

    证明设 a>b。

    1。显然当 b=0。gcd(a,b)=a。此时 x=1。y=0;

    2,ab!=0 时。设 ax1+by1=gcd(a,b);

      bx2+(a mod b)y2=gcd(b,a mod b);

      依据朴素的欧几里德原理有 gcd(a,b)=gcd(b,a mod b);

      则:ax1+by1=bx2+(a mod b)y2;

      即:ax1+by1=bx2+(a-(a/b)*b)y2=ay2+bx2-(a/b)*by2;

      依据恒等定理得:x1=y2; y1=x2-(a/b)*y2;

       这样我们就得到了求解 x1,y1 的方法:x1。y1 的值基于 x2,y2.

      上面的思想是以递归定义的,由于 gcd 不断的递归求解一定会有个时候 b=0,所以递归能够结束。

    递归代码:

    __int64 exgcd(__int64 a,__int64 b,__int64 &x1,__int64 &y1)
    {
        __int64 t,d;
        if(b==0){
            x1=1;
            y1=0;
            return a;
        }
        d=exgcd(b,a%b,x1,y1);
        t=x1;
        x1=y1;
        y1=t-a/b*y1;
        return d;
    }


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

    (1)求解不定方程。

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

    (3)求解模的逆元;

    补充定理:

    1.设a,b,c为随意整数。若方程ax+by=c的一组整数解为(x0。y0),
    则它的随意整数解都能够写成(x0+kb',y0-ka'),当中a'=a/gcd(a。b),b'=b/gcd(a,b),k为随意整数
    2.定理:若ax+by=g。(g=gcd(a,b),即g是a,b的最大公约数)有整数解(x1,y1);则ax+by=c(c是g的倍数)有整数解(cx1/g,cy1/g)


  • 相关阅读:
    Java实现 计蒜客 拯救行动
    Java实现 计蒜客 拯救行动
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 174 地下城游戏
    Java实现 LeetCode 173 二叉搜索树迭代器
    Java实现 LeetCode 173 二叉搜索树迭代器
    Visual Studio的SDK配置
    怎样使用CMenu类
    mfc menu用法一
  • 原文地址:https://www.cnblogs.com/yxwkf/p/5205585.html
Copyright © 2011-2022 走看看