$\Theta(n)$求$1...n$的乘法逆元

\[ p = m * d + r\]

也就是\(p\)为被除数,\(d\)为除数,\(m\)为商,\(r\)为余数

\[ m = [\frac{p}{d}]\]

\[ r = p \mod d\]

\[ m * d + r \equiv 0\mod p\]

两边同乘\(d^{-1}r^{-1}\)

\[m * r^{-1} + d^{-1} \equiv 0\mod p\]

移项得

\[ d^{-1} \equiv -m * r^{-1}\mod p\]

因为 \[m = [\frac{p}{d}]\]

所以\[d^{-1} \equiv -[\frac{p}{d}] * r^{-1}\]

因为 \[ r = p\mod d\]

\[ d^{-1} \equiv -[\frac{p}{d}]*[p\mod d]^{-1} \mod p\]

我们可以记个数组\(ans[]\)

初始把\(ans[1] = 1\)

然后根据前面的\(ans[p\mod d]\)推出后面的\(ans[d]\)

Code

#include <bits/stdc++.h>

#define ll long long
const int MaxN = 3000000 + 10;

using namespace std;

inline int read() {
    int cnt = 0, opt = 1;
    char ch = getchar();

    for (; ! isalnum(ch); ch = getchar())
        if (ch == '-')  opt = 0;
    for (; isalnum(ch); ch = getchar())
        cnt = cnt * 10 + ch - 48;

    return opt ? cnt : -cnt;
}

ll n, p;
ll ans[MaxN];

int main() {
    n = read(), p = read();

    ans[1] = 1;

    printf("%lld\n", ans[1]);

    for (int i = 2; i <= n; ++ i) {
        ans[i] = (p - (p / i)) * ans[p % i] % p;
        printf("%lld\n", ans[i]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/chz-hc/p/12221253.html