题目链接:https://www.luogu.com.cn/problem/P3811
若a*x≡1(mod p)
则称x为a对p的逆元,记为inv[x]=a
逆元一般用来求形如(a/b)%p的式子的值
(详见这位大佬的博客)
exgcd
还记得这个式子吗?a*x≡1(mod p)
这个式子可以转化为a*x+p*y=1
这个时候就可以用exgcd来求逆元
BUT,对于这道题来说,exgcd的O(n log n)的时间复杂度会TLE,只能拿80分,最后一个点T掉了(但是对于普通的题来说这个方法还挺好用的)
80分的code:
#include<bits/stdc++.h>
using namespace std;
void exgcd(int &x,int &y,int a,int b)
{
if(!b)
{
x=1;
y=0;
return;
}
exgcd(x,y,b,a%b);
int t=x;
x=y;
y=t-a/b*y;
}
int main()
{
int n,p;
scanf("%d %d",&n,&p);
for(int i=1;i<=n;i++)
{
int x=0,y=0;
exgcd(x,y,i,p);
printf("%d\n",(x%p+p)%p);
}
return 0;
}
费马小定理
费马小定理:若p为素数,a为正整数,且a、p互质。 则有:\[ a^{p-1} \equiv 1 (\bmod {p}) \]
这个我们就可以发现它这个式子右边刚好为 1 。
所以我们就可以放入原式,就可以得到:
a^(p-1) ≡1 (mod p)
两边同除以a
a^(p-2) ≡1/a (mod p)
什么?这可是数论,还敢写1/a
应该写a^(p-2) ≡ inv(a) (mod p)
但是,仍然会TLE......
于是代码略......
P.S:感谢这两位大佬的blog:
https://www.luogu.com.cn/blog/zjp-shadow/cheng-fa-ni-yuan)[https://www.luogu.com.cn/blog/zjp-shadow/cheng-fa-ni-yuan
https://blog.csdn.net/yu121380/article/details/81188274
逆元的线性递推式
经过一番神奇的操作,别问我怎么搞的,我也不会,得到了下面的式子:
inv[i]=(p-p/i)*inv[p%i]%p;
于是,就有了这个AC代码(源自https://www.cnblogs.com/song-/p/9724555.html):
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define ll long long
#define N 10101010
using namespace std;
int n,p;
ll inv[N];
int main()
{
scanf("%d%d",&n,&p);
inv[1]=1;
printf("1\n");
for(int i=2;i<=n;i++){
inv[i]=(p-p/i)*inv[p%i]%p;
printf("%lld\n",inv[i]);
}
return 0;
}
原文:https://www.cnblogs.com/juruo-zzt/p/12045915.html