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

    推荐博客 :https://www.cnblogs.com/frog112111/archive/2012/08/19/2646012.html

    欧几里得又称为辗转相除法,是用来求最大公约数的一种高效的算法。

    核心就是一点 gcd(a, b) = gcd(b, a%b) ;

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

    扩展欧几里得

    两个不定方程(扩展欧几里得算法作用之处)

    定理:若ax+by=g,(g=gcd(a,b),即g是a,b的最大公约数)有整数解(x1,y1)

      则ax+by=c(c是g的倍数)有整数解(cx1/g,cy1/g) , 若 c 不是 gcd 的倍数,则其不存在整数解。

      设ExtendedGCD为扩展欧几里得算法,它接受两个整数a,b,返回两个整数x,y。

      若有ax+by=gcd(a,b),则ExtendedGCD(a,b)可求x,y。

    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.设a, b, c为任意整数,g=gcd(a,b),方程ax+by=c的一组解是(x0,y0),则
    当c是g的倍数时ax+by=c的一组解是(x0c/g, y0c/g);当c不是g的倍数时无整数解。

    代码示例:

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

     紫书上的 exgcd

    void exgcd(int a, int b, int &d, int &x, int &y){ // d 表示gcd
        if (b == 0) {d = a; x = 1; y = 0; }
        else {exgcd(b, a%b, d, y, x); y -= (a/b)*x; }
    }
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    Leetcode:42. Trapping Rain Water
    Leetcode: 41. First Missing Positive
    Leetcode: 40. Combination Sum II
    多项式全家桶
    BZOJ 3878 [AHOI&JSOI2014]奇怪的计算器 (线段树)
    BZOJ 2959 长跑 (LCT+并查集)
    BZOJ 3028 食物 (生成函数+数学题)
    luogu P5504 [JSOI2011]柠檬
    hdu 6399 City Development
    luogu P3826 [NOI2017]蔬菜
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/7830933.html
Copyright © 2011-2022 走看看