逆元

乘法逆元

定义

如果存在整数\(a,x,b\)满足线性同余方程 \(\large ax\equiv1\pmod{b}\)
(即将\(ax\)除以整数\(b\)之后的余数为1),则我们称:

\(a\)关于模\(b\)的乘法逆元为\(x\),表示为\(\large a\equiv x^{-1}\pmod{b}\).

\(x\)关于模\(b\)的乘法逆元为\(a\),表示为\(\large x\equiv a^{-1}\pmod{b}\).

在同余方程中,若\(a\)\(b\)互质, 则一定存在一个正整数解\(x\), 满足\(x<b\);若\(a\)\(b\)不互质, 则一定不存在正整数解\(x\).所以逆元要求\(a\)\(b\)互质


扩展欧几里得算法

前置芝士

扩展欧几里德算法是用来在已知\(a, b\)求解一组\(x,y\),使它们满足裴蜀等式:$ \large a x + b y = g c d ( a , b ) = d $
(解一定存在,根据数论中的相关定理)。

扩展欧几里德常用在求解模线性方程及方程组中。

如何求解\(x,y\):

1.显然地,当\(b = 0\)时,\(gcd(a,b) = a\)\(x = 1\),\(y = 0\). 即\(\large a * 1 + b * 0 = a\).

2.当\(b \ne 0\) 时:

\(\large ax_1 + by_1 = gcd(a,b)\)

在下一个exgcd中有:\(\large bx_2 + (a \% b)y_2 = gcd(a,a \% b)\)

由欧几里得原理:\(\large gcd(a,b) = gcd(b,a \% b)\)

因此:\(\large ax_1 + by_1 = bx_2 + (a \% b)y_2\)

即:\(\large ax_1 + by_1 = bx_2 + (a - a / b * b)y_2\)

\(\Rightarrow\) \(\large ax_1 + by_1 = ay_2 + bx_2 - (a / b)by_2\)

所以,\(\large x_1 = y_2,y_1 = x_2 - (a / b)y_2\)

综上:\(x_1\),\(y_1\)的值是基于\(x_2\),\(y_2\)的。


问题来了,那么这和逆元有啥关系嘞?

自己灵性理解了下:

对于同余方程:\(\large ax\equiv1\pmod{b}\)

我们把它转化成\(\large ax + by = 1\)的形式。

这样,求出这个不定方程中\(x\)的整数解就可以啦。
而一般来说我们要求的通常是最小正整数解。

代码如下:

int exgcd(int a,int b,int &x,int &y)//扩展欧几里得
{
	if (!b)
	{
		x = 1,y = 0;
		return a;
	}
	int t = exgcd(b,a % b,x,y);
	int x1 = x,y1 = y;
	x = y1;
	y = x1 - a / b * y1;
	return t;
}

int main()
{
	int a,b,x,y,ans;
	int d = exgcd(a,b,x,y);
	if (d == 1)
		ans = (x % b + b) % b;//求最小正整数解
	else
		ans = -1;
	return 0;
}

费马小定理

前置芝士

定理:

\(b\)是质数,\(a\)\(b\)互质,那么有:\(\large a^{b - 1}\equiv 1\pmod{b}\)

至于证明我也不会啊qaq,用它就完事了!

[某度某科]:费马小定理


那么问题又来了,这又和逆元有什么关系哦?

本人灵性理解2:

我们要求\(a\)的乘法逆元\(x\)

因为有: \(\large ax\equiv1\pmod{b}\)

又因为:\(\large a^{b - 1}\equiv 1\pmod{b}\)

根据\(\large a * a^{b - 2} = a^{b - 1}\)

所以:\(\large x = a ^ {b - 2}\)

这个我们用快速幂来求解即可。

代码:

int qpower(int a,int b,int p)
{
   int ans = 1;
   while(b)
   {
   	if (b & 1)
   		ans = (long long)ans * a % p;
   	a = (long long)a * a % p;
   	b >>= 1;
   }
   return ans;
}

int main()
{
   int a,b;
   if (a % b == 0)
   {
   	cout << "impossible";
   	return 0; 
   }
   int ans = qpower(a,b - 2,b);//快速幂求a的b - 2次方
   cout << ans;
   return 0;
}
posted @ 2021-11-10 22:47  Carlotta24  阅读(88)  评论(0)    收藏  举报