zoukankan      html  css  js  c++  java
  • 【算法】欧几里得——GCD引发的讨论

    欧几里得算法

    任务

    求两个数a,b的最大公约数gcd(a,b)

    说明

    由贝祖定理[若设a,b是整数,则存在整数x,y,使得ax+by=gcd(a,b)]得,gcd(a,b)=(b,a-b),其中a≥b。通过这样不断的迭代,知道b=0,就是原来数对的最大公约数。考虑到只使用减法会超时,我们观察到如果a-b仍然大于b的话,要进行一次同样的操作,就把a减到不足b为止,所以有gcd(a,b)=gcd(b,a mod b)。由此可以在log的时间内求出两个数的gcd。

    程序

    int gcd(int a,int b);

    复杂度

    O(logN),其中N和a,b同阶

    输入

    a,b两个整数

    输出

    a,b的最大公约数

    代码

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

    扩展欧几里得

    任务

    求出A,B的最大公约数,且求出X,Y满足AX+BY=GCD(A,B)。

    说明

    要求X,Y,满足:AX+BY=GCD(A,B)。
    当B=0时,有X=1,Y=0时等式成立。
    当B>0时,在欧几里得算法的基础上,已知:
    GCD(A,B)=GCD(B,A mod B)
    先递归楸树X’,Y’满足:
    BX’+(A mod B)Y’ = GCD(B,A mod B) = GCD(A,B)
    然后可以回推,我们将上式化简得:
    BX’+(A-A/B*B)Y’=GCD(A,B)
    AY’+BX’-(A/B)*BY’=GCD(A,B)
    这里除法指整除。把含B的因式提取一个B,可得:
    AY’+B(X’-A/B*Y’)=GCD(A,B)
    故X=Y’,Y=X’-A/B&Y’

    程序

    int extend_gcd(int a,int b,int &x,int &y);

    复杂度

    O(logN),其中N和a,b同阶

    输入

    a,b两个整数
    &x,&y引用,ax+by=GCD(a,b)的一组解

    输出

    a,b的最大公约数
    调用后x,y满足方程ax+by=GCD(a,b)。

    代码

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

    参考文章:
    ACM国际大学生程序设计竞赛:算法与实现
    百度百科

  • 相关阅读:
    NOIP2008双栈排序[二分图染色|栈|DP]
    洛谷P1108 低价购买[DP | LIS方案数]
    洛谷P1330封锁阳光大学[二分图染色]
    NOIP模板整理计划
    期中考试
    UVA 10564 Paths through the Hourglass[DP 打印]
    UVA 11404 Palindromic Subsequence[DP LCS 打印]
    POJ2479 Maximum sum[DP|最大子段和]
    POJ3160 Father Christmas flymouse[强连通分量 缩点 DP]
    UVA11324 The Largest Clique[强连通分量 缩点 DP]
  • 原文地址:https://www.cnblogs.com/BoilTask/p/12569513.html
Copyright © 2011-2022 走看看