洛谷P3811 【模板】乘法逆元

  • 题意 :RT

  • 题解:这题比较坑,我用了扩欧和快速幂都T了,后来学习了一种线性算法,用来求一连串数的逆元.

    ​ 首先我们知道 \(p\equiv0 \;(mod\,p)\) .

    ​ 设: \(p=k*i +r\),\(k\)\(p/i\)的商,\(r\)是余数.

    ​ 于是我们得到\(k*i+r\equiv 0\;(mod\;p)\).

    ​ 然后乘上\(i^{-1},r^{-1}\)并移项得到:

    \(i^{-1}\equiv-k*r^{-1}\;(mod\;p)\) .

    \(i^{-1}\equiv-\lfloor\frac{p}{i}\rfloor*(p\;mod\;i)^{-1}\ (mod\;p)\).

    ​ 而对于\(p\;mod\;i\),一定有\(p\;mod\;i<i\),所以我们用\(f[i]\)来表示\(i\)的逆元.

    ​ 最后不要忘了取正,因为在等式右边加上\(p\)原式不变,所以最后的公式为:

    \(i^{-1}\equiv(p-\lfloor\frac{p}{i}\rfloor)*(p\;mod\;i)^{-1}\ (mod\;p)\).

  • 代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <stack>
    #include <queue>
    #include <vector>
    #include <map>
    #include <set>
    #include <unordered_set>
    #include <unordered_map>
    #define ll long long
    #define fi first
    #define se second
    #define pb push_back
    #define me memset
    const int N = 30000528;
    const int mod = 1e9 + 7;
    using namespace std;
    typedef pair<int,int> PII;
    typedef pair<long,long> PLL;
    
    ll n,p;
    ll f[N];
    int main() {
        scanf("%d %d",&n,&p);
        f[1]=1;
        puts("1");
        for(ll i=2;i<=n;++i){
            f[i]=(p-p/i)*f[p%i]%p;
            printf("%lld\n",f[i]);
        }
        return 0;
    }
    
原文地址:https://www.cnblogs.com/lr599909928/p/12850557.html