乘法逆元详解【费马小定理+扩展欧几里得算法】

乘法逆元详解【费马小定理+扩展欧几里得算法】

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_37656398/article/details/81434277

乘法逆元

何为乘法逆元?

对于两个数 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>
posted @ 2019-08-15 09:15  Cherish486  阅读(45)  评论(0编辑  收藏  举报