费马小定理求逆元
逆元定义
若 \(a*x\equiv1 \pmod {b}\),且 \(a\) 与 \(b\) 互质,那么我们就能定义:
\(x\) 为 \(a\) 的逆元,记为 \(a^{-1}\),所以我们也可以称 \(x\) 为 \(a\) 在 \(\bmod b\) 意义下的倒数,
所以对于 \(\displaystyle\frac{a}{b} \pmod {p}\) ,我们就可以求出 \(b\) 在 \(\bmod {p}\) 下的逆元,然后乘上 \(a\) ,再 \(\bmod {p}\),就是这个分数的值了。
费马小定理求逆元
这个做法要利用 费马小定理
若 \(p\) 为素数,\(a\) 为正整数,且 \(a\),\(p\) 互质。
则有 \(a^{p-1} \equiv 1 (\bmod {p})\)。
这个我们就可以发现它这个式子右边刚好为 \(1\) 。
所以我们就可以放入原式,就可以得到:
\[a*x\equiv 1 \pmod p
\]
\[a*x\equiv a^{p-1} \pmod p
\]
\[x \equiv a^{p-2} \pmod p
\]
所以我们可以用快速幂来算出 \(a^{p-2} \pmod p\)的值,这个数就是它的逆元了
代码也很简单:
#include <bits/stdc++.h>
using namespace std;
long long normalPower(long long base,long long power,long long k)
{
long long result=1;
while(power>0)
{
if(power&1) result=result*base%k;
power>>=1;
base=(base*base)%k;
}
return result;
}
int main()
{
//freopen(".in","r",stdin);
//fvreopen(".out","w",stdout);
ios::sync_with_stdio(false);
cin.tie(nullptr);cout.tie(nullptr);
int n,p;
cin>>n>>p;
for(int i=1;i<=n;i++) cout<<normalPower(i,p-2,p)<<endl;;
return 0;
}
时间复杂度为 \(O(\log p)\),不适用于多组数据。

浙公网安备 33010602011771号