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

  • 相关阅读:
    poj 2485 Highways 最小生成树
    hdu 3415 Max Sum of MaxKsubsequence
    poj 3026 Borg Maze
    poj 2823 Sliding Window 单调队列
    poj 1258 AgriNet
    hdu 1045 Fire Net (二分图匹配)
    poj 1789 Truck History MST(最小生成树)
    fafu 1181 割点
    减肥瘦身健康秘方
    人生的问题
  • 原文地址:https://www.cnblogs.com/Accepting/p/12582711.html
Copyright © 2011-2022 走看看