1.逆元是个什么东西
首先这里有个式子: ( ( ( a b \frac{a}{b} ba ) ) ) m o d mod mod p p p,这个式子的答案怎么求呢??
A 直接求不行吗?
Q别想了不能。我们发现一个分数 mod 一个整数时是不能直接模运算的,但是可以进行乘法运算,我们就要用到逆元(大概可以看做一个数%p意义下的倒数吧)
除以一个数模 p p p,就等于乘以一个数在mod p意义下的逆元
也就是说,它的定义可以表示为 a x ≡ 1 ax≡1 ax≡1 ( m o d (mod (mod n ) n) n)
2. 求逆元的方法之——费马小定理
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
ll a,b,p,r;
ll n;
ll ksm(ll a,ll b,ll p)
{
ll r=1;
while(b)
{
if(b&1)r=r*a%p;
b>>=1;
a=a*a%p;
}
return r;
}
int main()
{
cin>>n>>p;
for(int i=1;i<=n;i++)
{
ll hh=ksm(i,p-2,p);
cout<
3.方法二——扩展欧几里得
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
void read(int &x)
{
int f=1;x=0;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
x=f*x;
}
int n,p;
void exgcd(int a,int b,int &x,int &y)
{
int t;
if(b==0)
{
x=1;y=0;return;
}
exgcd(b,a%b,x,y);
t=x;x=y;y=t-(a/b)*y;
}
int main()
{
read(n);read(p);
register int x,y;
for(int i=1;i<=n;i++)
{
exgcd(i,p,x,y);
cout<<(x+p)%p;
putchar('\n');
}
}
4.线性求逆元
虽然已经有2种方法,但是对于这样的题模板还是会 T T T
于是我们不得不学习线性逆元
就可以使用递推法 。
i i i 模 p p p 意义下的逆元 i n v ( i ) inv(i) inv(i)可表示为 :
i n v ( i ) = − ⌊ p i ⌋ × i n v ( p % i ) % p \large inv(i) = -\lfloor \frac{p}{i}\rfloor \times inv(p\% i)\% p inv(i)=−⌊ip⌋×inv(p%i)%p
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
void read(int &x)
{
int f=1;x=0;char s=getchar();
while(s>'9'||s<'0'){if(s=='-')f=-1;s=getchar();}
while(s<='9'&&s>='0'){x=x*10+s-'0';s=getchar();}
x=f*x;
}
int n,p;
ll a[5000005];
int main()
{
read(n);read(p);
a[1]=1;
for(int i=2;i<=n;i++)
{
a[i]=(ll)p-(p/i)*a[p%i]%p;
}
for(int i=1;i<=n;i++)
printf("%d\n",a[i]);
}