数学上的乘法逆元就是倒数,即 aa 的逆元是 1a\dfrac{1}{a}(或 a1a^{-1}),也即与 aa 相乘得 11 的数。若 ax=1ax=1,则 xxaa 的乘法逆元。

这里我们讨论关于取模运算的乘法逆元,即对于整数 aa,与 aa 互质的数 bb 作为模数,当整数 xx 满足 axmodb1ax \mod b≡1 时,称 xxaa 关于模 bb 的逆元,代码表示就是 a * x % b == 1

在算法竞赛中,经常会遇到求解数据很大,则输出模 109+710^9+7 的解这类要求。加法、减法、乘法等操作,基于同余理论直接取模即可。但遇到除法时,某步中间结果不一定能完成整除,就无法求解了。

举个例子:求 3×63\dfrac{3\times 6}{3}77 取模的结果。我们直接算出 3×63\dfrac{3\times 6}{3} 的结果是 66,对 77 取模得最终答案是 66

但我们通常面对的问题是中间结果超过long long甚至int的范围,而不得不在每一步基于同余理论取模,我们用这个例子尝试一下:

还是求 3×63\dfrac{3\times 6}{3}

  1. 3×6=183\times 6=18
  2. 18mod7=418\mod 7=4
  3. 44 这个中间结果再做 43\dfrac{4}{3} 无法整除,就无法进行下去了。

但我们可以求出除数 33 关于模数 77 的逆元 55(根据逆元定义,55 符合 3×5mod7=13\times 5 \mod 7=1),从而,用乘以 55 代替除以 33

上述第二步除法变乘法:4×5=204\times 5=2020mod7=620 \mod 7=6

从而也计算出了正确的结果 66

乘法逆元的作用就是:

mm 是一个天文数字,aabb 已知,预期要计算(假设答案为 ccmamodb\dfrac{m}{a}\mod b

对于 aa 的逆元 dd,能够满足

m×dmodb=mamodb=cm\times d\mod b=\dfrac{m}{a}\mod b=c

在有些问题中,无法计算最终值很大的 mm,只能得到基于同余的一个中间值 mmodb=em\mod b=e 来计算 eamodb\dfrac{e}{a}\mod b,而 ee 可能无法整除 aa,就可以用 aa 的逆元 dd,来计算 e×dmodbe\times d\mod b

故而我们需要一个算法求除数取模逆元,从而在四则运算取模的任务中,用逆元将除法转为乘法。

#include<cstdio>
using namespace std;
void exgcd(int a,int b,int &x,int &y){
	if(b==0){x=1,y=0;return;}
	exgcd(b,a%b,y,x);
	y-=(a/b)*x;
}
int get_inv(int a,int p){
	int x=1,y=0;
	exgcd(a,p,x,y);//x=a_inv,a*a_inv+p*y=1
	return (x%p+p)%p;
}
int a,p;
int main(){
	scanf("%d%d",&a,&p);
	printf("%d",get_inv(a,p));
}

以下copy自百度百科(6

乘法逆元,是指数学领域群 GG 中任意一个元素 aa,都在 GG 中有唯一的逆元 aa',具有性质 a×a=a×a=ea×a'=a'×a=e,其中 ee 为该群的单位元

例如:44 关于 1177 的乘法逆元为多少?

4x1mod74x≡1\mod7

这个方程等价于求一个 xxkk,满足

4x=7k+14x=7k+1

其中 xxkk 都是整数。

ax1modfax≡1\mod f, 则称 aa 关于 11ff 的乘法逆元为 xx。也可表示为 ax1(modf)ax≡1(\mod f)

aaff 互素时,aa 关于模 ff 的乘法逆元有解。如果不互素,则无解。如果 ff素数,则从 11f1f-1 的任意数都与 ff 互素,即在 11f1f-1 之间都恰好有一个关于模 ff 的乘法逆元。

例如,求 55 关于模 1414 的乘法逆元:

14=5×2+414=5×2+4

5=4×5=4×1+11+1

说明 551414 互素,存在 55 关于 1414 的乘法逆元。

1=54=5(145×2)=5×3141=5-4=5-(14-5×2)=5×3-14

因此,55 关于模 1414 的乘法逆元为 33

乘法逆元的定义及用途,以及求逆元的三种算法:扩展欧几里得、费马小定理、递推求逆元。


  • P类问题:存在多项式时间算法的问题,即在多项式时间内可解的问题

    例如:冒泡排序,快速排序等问题

  • NP类问题:能在多项式时间内验证出一个正确解的问题,也就是说这个问题不一定在多项式时间内可解,但可以在多项式时间内验证

    例如:大数分解问题,比如 180576180576 这个数让你拆成两个数相乘,必须是三位乘以三位的,可能很久都解不出来(如果是一个很大很大的数的话),但是我告诉你这是 352×513352\times 513 得到的,那么很简单就能在多项式时间内验证是否正确,这就是NP问题

  • NPC类问题:存在这样一个NP问题,所有的NP问题都可以约化成它

  • NP-Hard类问题:所有的NP问题都可以约化成它

c的