简述逆元+两种算法

逆元:用于计算式子 (a/b) mod p,当b十分大的时候,可以利用b的逆元inv(b),原式即为(a*inv(b) mod p)。一个类似于b的倒数的家伙,要注意的是b的逆元并不唯一,而且要说成是b模p的情况下逆元是多少。逆元不是一定存在的,必须是b与p互质(两者公因数仅有1)才存在逆元。

求解逆元的方法,目前博主学了两个:

  1. 利用费马小定理快速幂求逆元。
  2. 利用拓展欧几里得算法求逆元。

1.利用费马小定理求解逆元:(这个解法仅适用于p为质数)公式为:inv(a)≡a的p−2次幂。

代码实现:

long long ksm(long long a,long long b)
{
	if(b<0) return 0;
	long long ret=1;
	a%=mod;
	while(b)
	{
		if(b&1ll)
		ret=(ret*a)%mod;
		b>>=1;
		a=(a*a)%mod;
	}
	return ret;
}
long long inv(long long a)
{
		return ksm(a,mod-2);
}

2.利用拓展欧几里得算法实现。

代码实现:

typedef long long ll;
ll exgcd(ll a,ll b,ll &x,ll &y){
	if(!b)
	{
		x=1;
		y=0;
		return a;
	}
	int r=exgcd(b,a%b,x,y);
	int t=y;
	y=x-(a/b)*y;
	x=t;
	return r;
}

在模板中,a为要求逆元的数,b为a要模的数即为mod,x为a mod b的逆元,y为b mod a的逆元。(mod一会是个数词,一会是个动词,嘎嘎),r为a,b的最大公约数,r若不为1,则逆元不存在。

猜你喜欢

转载自blog.csdn.net/Lyyforever1220/article/details/99571783