\(\texttt{例题}\)
给定 \(n,p\), 求 \(1\sim n\) 中所有整数在模 \(p\) 意义下的乘法逆元。
保证 \(p\) 为质数且 \(p>n\)。
\(\texttt{乘法逆元}\)
A:什么是在模 \(p\) 意义下的乘法逆元?
Q:\(a\) 在模 \(p\) 意义下的乘法逆元是满足 \(ax\equiv1(mod\quad p)\) 的 \(x\) 的值。\(x\) 又可以写成 \(a^{-1}\)。
\(\texttt{方法一:递推}\)
适用于求大范围内所有数的逆元
设 \(k,r\) 满足 \(p/i=k......r\)。
则有 \(k=\lfloor \dfrac{p}{i}\rfloor,\quad r=p\%i\)
那么原方程变为:
等式两边同乘 \(i^{-1}\)
等式两边同乘 \(r^{-1}\)
因为 \(p\%i<i\),所以 \(p\%i\) 的逆元一定是之前处理过的。
因此,我们就得到了递推式。设 \(f(i)=i^{-1}\),则有:
\(\texttt{代码}\)
#include <bits/stdc++.h>
using namespace std;
long long a[20000528],n,p;
int main()
{
cin>>n>>p;
a[1]=1;//无论p是多少,1的逆元一定是1
cout<<1<<endl;
for(register long long i=2; i<=n; i++)
{
a[i]=(p-p/i)*a[p%i]%p;//递推式
printf("%lld\n",a[i]);
}
return 0;
}
\(\texttt{方法二:扩展欧几里得}\)
适用于单个乘法逆元求解
对于 \(ax\equiv 1(mod\quad p)\) 这个式同余方程,进行化简后得:
因为 \(p\) 为质数且 \(p>n\),所以 \(gcd(a,p)=1\),于是原式又可以写成:
然后便可以用扩展欧几里得求解。
戳这里
© 著作权归作者所有
相关热门文章
发表评论