zoukankan      html  css  js  c++  java
  • GCD

    GCD-欧几里得定理(辗转相除)

    Elements

    (GCD(a,b)=GCD(b,a\%b))

    Confirmation

    (a=bk+c),显然有(c=a\%b)。设(d|a d|b),则

    [c=a-bk ]

    [frac{c}{d}=frac{a}{d}-frac{b}{d}k ]

    由右边的式子可知(frac{c}{d})为整数,即(d|c)所以对于(a,b)的公约数,它也会是(a\%b)的公约数。

    反过来也需要证明

    (d|b d|(a\%b)),我们还是可以像之前一样得到以下式子

    [frac{a\%b}{d}=frac{a}{d}-frac{b}{d}k ]

    [frac{a\%b}{d}+frac{b}{d}k=frac{a}{d} ]

    因为左边式子显然为整数,所以(frac{a}{d})也为整数,即(d|a),所以(b,a\%b)的公约数也是(a,b)的公约数。

    既然两式公约数都是相同的,那么最大公约数也会相同

    所以得到式子

    [gcd(a,b)=gcd(b,a\%b) ]

    Code

    所以我们可以写出一个递归式,层层深入,直到 (b%(a%b)==0),即正好为倍数整除时,递归回去就行了

    int gcd(int a,int b)
    {
    	if(b==0)
        	return a;
        return gcd(b,a%b);
    }
    

    最后的返回值自然为(a,b)的最大公因数

    EXGCD-扩展欧几里得定理

    目的:求(ax+by=gcd(a,b))的一组可行解
    证明

    [ax_1+by_1=gcd(a,b) ]

    [bx_2+(a\,mod\,b)y_2=gcd(b,a\,mod\,b) ]

    由欧几里得定理可知:

    [gcd(a,b)=gcd(b,a\,mod\,b) ]

    所以

    [ax_1+by_1=bx_2+(a\,mod\,b)y_2 ]

    又因为

    [a\,mod\,b=a-(lfloorfrac{a}{b} floor*b) ]

    所以

    [ax_1+by_1=bx_2+(a-(lfloorfrac{a}{b} floor*b))y_2 ]

    [ax_1+by_1=ay_2+bx_2-lfloorfrac{a}{b} floor*by_2=ay_2+b(x_2-lfloorfrac{a}{b} floor y_2) ]

    因为(a=a,b=b),所以

    [x_1=y_2 ]

    [y_1=x_2-lfloorfrac{a}{b} floor y_2 ]

    (x_2,y_2)不断代入递归求解直至(GCD)为0递归(x=1,y=0)回去求解,就像(GCD)一样的方法

    int Exgcd(int a,int b,int &x,int &y)
    {
        if (!b) 
        {
            x=1;y=0;
            return a;
        }
        int d=Exgcd(b,a%b,x,y);
        int t=x;
        x=y;
        y=t-(a/b)*y;
        return d;
    }
    

    返回的值为(GCD),在这个过程中计算(x,y)即可

  • 相关阅读:
    设计模式之备忘录模式
    特殊传参方式
    页面响应效率测试
    composer安装的包git无法提交的解决办法是因为安装的时候生成了.git隐藏文件
    数据结构和算法深入浅出理解
    中缀表达式转换为后缀表达式
    p2p技术
    【自动化测试】WebDriver使用
    pt-query-digest简介使用
    mac编译openJDK8
  • 原文地址:https://www.cnblogs.com/luoshuitianyi/p/10333713.html
Copyright © 2011-2022 走看看