费马小定理求逆元

逆元定义

\(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)\),不适用于多组数据。

posted @ 2025-08-17 19:44  simple_child  阅读(31)  评论(0)    收藏  举报