zoukankan      html  css  js  c++  java
  • 数论篇3——扩展欧几里得算法

    1、引入

    最大公约数gcd算法:

    辗转相除法

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

    最小公倍数lcm算法:

    根据 a*b = gcd(a,b) * lcm(a,b)

    有 lcm = a*b / gcd,避免溢出,推荐写成lcm = a / gcd *b

    int lcm(int a, int b) {
        return a / gcd(a, b) * b;
    }

    2、扩展欧几里得算法

    算法定义:

    算法实现

     

    也就是说,我们得到了一个和gcd算法中,gcd(m,n)=gcd(n,m%n)相似,自底向上的恒等式

     

    举个例子,就是

     

     如果想要x为正值,根据

     

     只再做一步:

    if (x < 0) {
        x += b; y -= a;
    }

    推广的一般情况(k为任意整数):

    $$ax+by=ax+by+dfrac {ab}{gcdleft( a,b ight) }-dfrac {ab}{gcdleft( a,b ight) }\egin{cases}x'=x+dfrac {b}{gcd }*k\ y'=y-dfrac {a}{gcd }* kend{cases}$$

    完整代码:

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

    扩展:

     

  • 相关阅读:
    稀疏自编码器和矢量化编程
    使用支持向量机训练mnist数据
    采用libsvm进行mnist训练
    支持向量机
    月下“毛景树”
    最小费用最大流模板
    最大流模板
    选学霸
    线段树 2
    线段树 1
  • 原文地址:https://www.cnblogs.com/czc1999/p/11687006.html
Copyright © 2011-2022 走看看