题解 P3811 【【模板】乘法逆元】

· · 题解

先引入一个相关问题:

如何快速求解1~n的阶乘逆元?

首先求出n!的逆元,(n-1)!的逆元是等于n!的逆元乘n。

设P(x)为x的逆元,可以这样简洁的证明:

P(n!)\times x=\frac{1}{n!} \times x P(n!) \times n=\frac{1}{(n-1)!}

那么同理,我们可以求到1~n的所有数的阶乘的逆元。

好了相关问题结束。

那么我们知道了n!的逆元,我们怎么求n的逆元呢?

当然直接乘上(n-1)!就可以啦!

证明和上面差不多:

\frac{1}{n!}=P(n!) \frac{1}{n!} \times (n-1)!=\frac{1}{n}=P(n)=P(n!)\times (n-1)!

综上:P(n)=P(n!)\times (n-1)!

$n!$的逆元可以一次快速幂求出吧! 最后从大到小用上面综上里的公式依次求出逆元,别忘了$\%p$。 代码如下: ```cpp #include <bits/stdc++.h> using namespace std; long long n; long long p; long long c[3000006]; long long fast(long long x,long long y) { long long an=1; while(y) { if(y&1) an=(an*x)%p; x=(x*x)%p; y>>=1; } return an; } long long ans[3000006]; int main() { scanf("%lld%lld",&n,&p); c[0]=1; for(long long i=1;i<=n;i++) c[i]=(c[i-1]*i)%p; long long last=fast(c[n],p-2); long long k; for(int i=n;i>=1;i--) { k=(last*i)%p; ans[i]=(last*c[i-1])%p; last=k; } for(int i=1;i<=n;i++) printf("%lld\n",ans[i]); return 0; } ```