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

    乘法逆元问题,常常以这这样的形式出现

      a/mod )=a*(p1)( mod p),b是关于p的逆元。

    求解乘法逆元的几种方法:

    1 费马小定理,a在模p下的逆元,要求p为质数。

    ll fpm(ll x, ll power, ll mod) {
        x %= mod;
        ll ans = 1;
        for (; power; power >>= 1, (x *= x) %= mod)
            if(power & 1) (ans *= x) %= mod;
        return ans;
    }
    int main() {
        ll x = fpm(a, p - 2, p); //x为a在mod p意义下的逆元
    }

    2 拓展欧几里得。

      exgcd,求a在模p下的逆元,要求a和p互质,但是p不一定是质数。

      code:

    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;
        printf ("%d
    ", x); //x是a在mod p下的逆元
    }

    3 线性乘法

      常用于求一连串数字对于一个 mod p 的逆元。要求p为质数

      code:

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

    证明: p=k*i+r,对p取模可得,k*i+r=0(mod p),两端同时乘以i的逆元[i]和r的逆元[r]可得,k*[r]+[i]=0(mod p),

    [i]=-k*[r]=-k*[p%i],k=p/i,所以[i]=(-p/i)*([p%i]),[i]=(p-p/i)*[p%i]%p;

    4 递推法求阶乘逆元:

      code:

    void init() {
        fact[0] = 1;
        for (int i = 1; i < maxn; i++) {
            fact[i] = fact[i - 1] * i %mod;
        }
        inv[maxn - 1] = power(fact[maxn - 1], mod - 2);
        for (int i = maxn - 2; i >= 0; i--) {
            inv[i] = inv[i + 1] * (i + 1) %mod;
        }
    }

     证明过程:设n!的逆元为[n],我们求一下(n-1)!的逆元。

      n!*[n]=1(mod p)    将n!拆开, (n-1)!*n*[n]=1(mod p)所以,(n-1)!的逆元就是n[n]。

    所以递推式inv[n]=inv[n+1]*(n+1)%p;

    https://blog.csdn.net/qq_35416331/article/details/81059747

  • 相关阅读:
    通过elasticsearch对日志进行搜索热词统计
    登陆获取shell时的配置文件加载过程
    linux共享库加载
    linux安全相关
    ELK常用API使用方法
    linux bash缓存
    redis主从架构及redis集群
    排查电脑的网络问题
    Logstash添加Protobuf解析插件
    Macaca上手体验
  • 原文地址:https://www.cnblogs.com/Accepting/p/12582711.html
Copyright © 2011-2022 走看看