• 扩展欧几里得算法


    前置知识

    斐蜀定理(贝祖定理)

    写在前面

    鸣谢:扩展欧几里得算法——exgcd

    Q:啥叫扩展欧几里得啊

    A:扩展欧几里得算法是用来在已知 (a, b) 求解一组 (x, y) ,使他们满足斐蜀等式: (ax + by = gcd(a, b) = d)

    尝试搞一下它

    先考虑一下比较简单的特殊情况,如果 (b = 0),那么 (gcd(a, b) = a),并显然存在一组解 (x = 1, y = 0)

    对于一般情况,设 (ax + by = gcd(a, b))

    根据欧几里得算法, (gcd(a, b) = gcd(b, a mod b))

    肯定存在式子 (bx_2 + (a mod b)y_2 = gcd(b, a mod b))

    [ herefore ax_1 + by_1 = bx_2 + (a !!mod b)y_2 ]

    [egin{alignedat}{3} ecause ax_1 + by_1 & = bx_2 + (a - a div b imes b)y_2 \ & = bx_2 + ay_2 - a div b imes b imes y_2 \ & = ay_2 + b(x_2 - a div b imes y_2) end{alignedat}]

    [ herefore x_1 = y_2 , y_1 = x_2 - a div b imes y_2 ]

    继续递推下去就好啦~

    实现代码:

    int exgcd(int a, int b, long long &x, long long &y)
    {
        if(b == 0) return x = 1, y = 0, a;
        int d = exgcd(b, a % b, y, x);//d的值实际上就是gcd(a,b),如果不需要的话可以不求
        return y -= a / b * x, d;
    }
    

    不过毕竟有扩欧这种帅气的名字,可不能只干这点活

    它还可以求逆元

    (x)(a) 在模 (p) 意义下的逆元,那么满足式子:

    [ax equiv 1 ]

    那么有:

    [ax + my = 1 ]

    然后用 (exgcd) 搞出 (x) 即可(这就是为啥 (a)(m) 一定要互质才能使得 (a) 在模 (m) 意义下有逆元)

    实现代码:

    long long inv(long long a,long long m)
    {
        long long x,y;
        long long d = exgcd(a, m, x, y);
        return d == 1 ? (x + m) % m : -1 ;//不互质就没有逆元
    }
    

    (The) (end.)

  • 相关阅读:
    c++运算符重载
    c++ const_cast
    SHL
    C++拷贝构造函数(深拷贝,浅拷贝)
    ps命令详解
    static 修饰符
    “宝洁八大问”整理篇
    linux grep命令
    C++操作符重载
    linux中删除指定日期之前的文件
  • 原文地址:https://www.cnblogs.com/Silymtics/p/13974684.html
Copyright © 2020-2023  润新知