乘法逆元详解【费马小定理+扩展欧几里得算法】
原
乘法逆元详解【费马小定理+扩展欧几里得算法】
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
乘法逆元
何为乘法逆元?
对于两个数 a , p a , p a , p a,pa,p a,p a,pa,pa,pp。
编程实现
费马小定理:
long long PowMod(long long a,int b) {
long long ret=1;
while(b) {
if(b&1)ret=ret*a%Mod;
a=a*a%Mod;
b>>=1;
}
return ret;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
程序内调用PowMod(a,Mod-2)
即可。
扩展欧几里得算法:
long long extend_gcd(long long a,long long b,long long &x,long long &y) {
if(a==0&&b==0)
return -1ll;
if(b==0)
{
x=1ll;
y=0ll;
return a;
}
long long d=extend_gcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
long long mod_reverse(long long a,long long n) {
long long x,y,d=extend_gcd(a,n,x,y);
if(d==1) {
if(x%n<=0)return x%n+n;
else return x%n;
} else return -1ll;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
递推计算阶乘的逆元:
f[0]=1;
for(int i=1;i<=N;i++)
f[i]=f[i-1]*i%Mod;
inv[0]=1;
inv[N]=PowMod(f[N],Mod-2);
for(int i=N-1;i>0;i--)
inv[i]=inv[i+1]*(i+1)%Mod;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
递推计算连续的数的逆元:
inv[1]=1;
for(int i=2;i<=N;i++)
inv[i]=(Mod-Mod/i)*inv[Mod%i]%Mod;
- 1
- 2
- 3
</div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-e44c3c0e64.css" rel="stylesheet">
</div>
</article>