乘法逆元求法

原创建时间:2018-08-05 08:24:19

数论中的重要内容

注意:本文只讨论模数为质数的情况,因为当模数为合数时,不一定所有数都有逆元

定义

\(\bmod\ p\)的意义下,我们把\(x\)的乘法逆元写作\(x^{-1}\)。乘法逆元有这样一条性质:

\[x \times x^{-1} \equiv 1\ (\bmod\ p) \]

乘法逆元有什么用呢?

模意义下的除法运算

除法运算对于模运算来说并不是「封闭」的,所以我们可以把除法转化成乘法

费马小定理求法

前置知识:「快速幂」

\(a^{p-1} \equiv 1 (\bmod\ p)%\)

经过变形,可得

\(a \times a^{p-2} \equiv 1(\bmod\ p)\)

由定义可得,\(a\)的乘法逆元就是\(a^{p-2}\)

这就要用到「快速幂」

inline int slowPower(int a, int b, int p) {
    int ans = 1;
    while (b) {
        if (b & 1) ans = 1ll * ans * a % p;
        a = 1ll * a * a % p;
        b >>= 1;
    }
    return ans;
}

inline int invMod(int x, int p) {
    return slowPower(x, p - 2, p);
}

代码实现

输出1到n的逆元

/* -- Basic Headers -- */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>

/* -- STL Iterators -- */
#include <vector>
#include <string>
#include <stack>
#include <queue>

/* -- External Headers -- */
#include <map>
#include <cmath>

/* -- Defined Functions -- */
#define For(a,x,y) for (int a = x; a <= y; ++a)
#define Forw(a,x,y) for (int a = x; a < y; ++a)
#define Bak(a,y,x) for (int a = y; a >= x; --a)

namespace FastIO {
    inline long long int getint() {
        long long int s = 0, x = 1;
        char ch = getchar();
        while (!isdigit(ch)) {
            if (ch == '-') x = -1;
            ch = getchar();
        }
        while (isdigit(ch)) {
            s = s * 10ll + ch - '0';
            ch = getchar();
        }
        return s * x;
    }
    inline void __basic_putint(long long int x) {
        if (x < 0) {
            x = -x;
            putchar('-');
        }
        if (x >= 10) __basic_putint(x / 10);
        putchar(x % 10 + '0');
    }
    
    inline void putint(long long int x, char external) {
        __basic_putint(x);
        putchar(external);
    }
}


namespace Solution {
    const int MAXN = 5000000 + 10;
    
    long long int n, k, HA, a[MAXN];
    long long int fac[MAXN], invf[MAXN];
    
    long long int SlowPower(long long int a, long long int x) {
        //  a^x mod m
        long long int ret = 1;
        if (x == 1) return a;
        while (x) {
            if (x & 1) ret = ret * a % HA;
            a = a * a % HA;
            x >>= 1;
        }
        return ret;
    }
}

signed main() {
    using namespace Solution;
    using namespace FastIO;
    n = getint(); HA = getint();
    fac[0] = 1;
    for (int i = 1; i <= n; ++i) {
        fac[i] = (fac[i - 1] * i) % HA;
    }
    invf[n] = SlowPower(fac[n], HA - 2);
    for (long long int i = n - 1; i >= 1; --i) {
        invf[i] = (invf[i + 1] * (i + 1)) % HA;
    }
    for (long long int i = 1; i <= n; ++i) {
        printf("%lld\n", (invf[i] * fac[i - 1]) % HA);
    }
    return 0;
}


posted @ 2019-10-26 20:20  Handwer  阅读(155)  评论(0编辑  收藏  举报