• 【墨鳌】【数论小结 01】【乘法逆元】【扩展欧几里得】


    数论小结

    1. 扩展欧几里得

    首先,根据辗转相除法,不难有:

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

    关于扩展欧几里得算法,是解决线性方程:\(ax+by=c\) 当且仅当,\(\gcd(a,b)|c\) 有解

    又因为,\(x,y\in\Z\),所以问题可以转化为,解线性方程:\(ax+by=\gcd(a,b)\) 这就是扩展欧几里得算法初始条件

    假设,我们有方程的一组解 \(x_0,y_0\), 则:

    \[ax_0+by_0=\gcd(a,b)=\gcd(b,a\%b)\qquad(1) \]

    于是,构造新的线性方程与其解 \(x_1,y_1\),满足:

    \[bx_1+(a\%b)y_1=\gcd(b,a\%b)\qquad(2) \]

    联立 \((1),(2)\) 式,我们有:

    \[ax_0+by_0=\gcd(a,b)=\gcd(b,a\%b)=bx_1+(a\%b)y_1\\ =bx_1+(a-\lfloor a/b\rfloor\times b)y_1\\ =ay_1+b(x_1-\lfloor a/b\rfloor y_1) \]

    结论一:

    \[\cases{ x_0\leftarrow y_1\\ y_0\leftarrow x_1-\lfloor a/b\rfloor y_1\\ } \]

    结论二:

    \[\cases{ x_0\leftarrow y_1\\ y_0\leftarrow x_1\\ a\leftarrow b\\ b\leftarrow a\%b\\ \gcd(a,b)\leftarrow \gcd(b,a\%b)\\ } \]

    于是可以考虑设计递归或者迭代代码。

    递归版本

        int ex_gcd(int a, int b, int &x, int &y) {
            if (b == 0) {
                x = 1, y = 0;
                return a;
            }
            int d = ex_gcd(b, a % b, y, x);// 注意:这里已经调换了x,y顺序
            y -= (a / b) * x;
            return d;
        }
    

    2. 乘法逆元(扩展欧几里得算法求解)

    问题描述

    求解 \(ax\equiv1\mod{n}\)

    \[ax\equiv1\mod n\\ \iff ax+ny\equiv1\mod n \]

    当且仅当,\(\gcd(a,n)=1\) 有解,求解 \(ax+ny=1\) 使用扩展欧几里得算法

    乘法逆元-代码

        int inv(int a, int n) {
            int x, y, d = ex_gcd(a, n, x, y);
            if (d == 1) {
                if (x % n <= 0)
                    return x % n + n;
                else
                    return x % n;
            }
            return -1;
        }
    
  • 相关阅读:
    python之模块与包
    python之异常处理
    python之os与json&pickle模块
    python之random、time与sys模块
    python之re模块
    python之匿名函数、递归与二分法
    python之内置函数
    python之迭代器、生成器及列表推导式
    python之第一对象,函数名的应用,闭包
    python之命名空间与作用域
  • 原文地址:https://www.cnblogs.com/JasonCow/p/16194513.html
Copyright © 2020-2023  润新知