zoukankan      html  css  js  c++  java
  • 乘法逆元

    乘法逆元

    定义:如果一个线性同余方程 ax ≡ 1 ( mod b ),则称 x 为 a mod b 的逆元,计做a^(-1) .只有两个数互素的时候才有乘法逆元,两个数不互素是没有乘法逆元的

    用途:乘法逆元一般用于求解解决模意义下分数值的问题。

    乘法逆元可以通过多种方法求得,下面介绍几种方法求乘法逆元。

    <1.扩展欧几里德求逆元

    exgcd(扩展欧几里德算法)求乘法逆元,原理同求解线性同于方程一样,将题目转化为:ax + by =1,求x,上代码:

    void Exgcd(ll a, ll b, ll &x, ll &y) {
        if (!b) x = 1, y = 0;
        else Exgcd(b, a % b, y, x), y -= a / b * x;
    }
    int main() {
        ll x, y;
        Exgcd (a, p, x, y);
        x = (x % p + p) % p;
        cout << x << endl;		 //x是a在mod p下的逆元
    }
    

    <2.快速幂求逆元

    原理:若p为素数,则根据费马小定理有: (a^{p - 1} ≡ 1(mod p));即 (a^{p - 2})就是a的乘法逆元

    若a,p互素,则根据费马小定理:(a^{φ(p)} ≡ 1(mod p));(费马小定理的一般形式),即(a^{φ(p) - 1})就是a的乘法逆元。

    这样参考快速幂和欧拉函数的模板就能求出逆元了。

    ❤️.线性求逆元

    如果要求很多的话,上面两种方法就会显得很慢,很可能会超时,所以下面来介绍一下如何线性求逆元:

    线性求逆元顾名思义,其时间复杂度为 O(n) ,其通过递推的思想解得区间内的所有逆元,x显然 inv[1]=1; inv[i]=−(p/i)∗inv[p%i];下面为模板代码:

    inv[1] = 1;
    for (int i = 2; i <= n; ++i) 
        inv[i] = (long long)-(p / i) * inv[p % i] % p;
    

    但是有些情况下上面代码会出现负数,所以我们可以将其修改为只输出正整数:

    inv[1] = 1;
    for (int i = 2; i <= n; ++i) 
        inv[i] = (long long)(p - p / i) * inv[p % i] % p;
    
  • 相关阅读:
    结对项目——自动生成小学四则运算题目
    个人项目作业
    自我介绍+软工5问
    团队作业3--需求改进&系统设计
    团队作业2-需求规格说明书
    团队项目-第一周
    结对项目:四则运算表达式生成程序
    个人项目作业--WC的实现
    自我介绍+软工五问
    团队作业3-需求改进&系统设计
  • 原文地址:https://www.cnblogs.com/StungYep/p/12252573.html
Copyright © 2011-2022 走看看