乘法逆元


定义:

对于正整数 $a$,$n$ ,如果 $ax \equiv 1(\bmod n)$,那么称 $x$ 的最小整数解为$a \bmod n$的逆元。

模运算性质:

$(a±b) \bmod p=(a \bmod p±b \bmod p) \bmod p$

$(a \cdot b) \bmod p=(a \bmod p \cdot b \bmod p) \bmod p$

但是是有缺陷的,

$\frac{a}{b}\pmod p$是否与$\frac{a \bmod p}{b \bmod p}$相等?显然不相等。

如何解决这个问题,考虑将除法转为乘法。

那就需要找到一个$b_{inv}$使得$\frac{a}{b} \bmod p= a \cdot b_{inv} \bmod p$,其实这个$b_{inv}$就是$b$在$\bmod p$意义下的乘法逆元。

性质:

设$\frac{a}{b} \equiv x(\bmod p)$ -------①

假设存在 $b_{inv}$ 满足$a \cdot b_{inv} \equiv x(\bmod p)$-------②

①②式两边同乘一个 $b$

得到

$a \equiv bx(\bmod p)$----- ③ 

$a \cdot b_{inv} \cdot b \equiv bx(\bmod p)$------④

根据模运算减法性质将两式相减得 $a(b_{inv} \cdot b -1) \equiv 0(\bmod p)$

因为我们在找$b$得乘法逆元,所以$a$的值任意,所以式子相当于$b_{inv} \cdot b -1 \equiv 0(\bmod p)$

即$b_{inv} \cdot b \equiv 1(\bmod p)$

因此我们只需要找到满足$b_{inv} \cdot b \equiv 1(\bmod p)$的数$b_{inv}$,就是 $b$ 在 $\bmod p$意义下的乘法逆元。

存在条件:

是否总存在一个$b_{inv}$使式子成立?

举个例子,$b=2,p=10$,此时$2 \cdot b_{inv} \equiv 1 (\bmod 10)$,显然不成立,所以逆元有存在条件。

由$b_{inv} \cdot b \equiv 1(\bmod p)$,我们设$b \cdot b_{inv} = kp+1$,设 $g$ 为 $gcd(b,p)$ 

那我们将原式拆解开得:$g \cdot b_1 \cdot b_{inv} = k \cdot g \cdot p_1 +1$,合并得 $g(b_1 \cdot b_{inv} - kp)=1$

因为我们在正整数范围内讨论这个问题,所以只能有$g=1$且 $b_1 \cdot b_{inv} - kp=1$

以上步骤均可逆,所以乘法逆元存在的条件是当且仅当 $b$,$p$ 互质。

求法:

Ⅰ.费马小定理

费马小定理:若 $p$ 是质数,则$b^{p-1} \equiv 1(\bmod p)$

我们可以将式子变形:$b \cdot b^{p-2} \equiv 1(\bmod p)$,所以 $b_{inv}=b^{p-2}$,结合快速幂模板可求解

int fast_pow(int a,int b,int mod){
	int res=1; a%=mod;
	while(b){
	    if(b&1) res=(res*a)%mod;
	    a=a*a%mod;b>>=1;
	}
	return res%mod;
}
int get(int b,int p){
     retrun fast_pow(b,p-2,p);
}

Ⅱ.扩展欧几里得算法

利用费马小定理有一个弊端,就是 $p$ 只能为质数。

扩展欧几里得算法:求$ax+by=gcd(a,b)$的一组 $x$,$y$.

则我们要凑出扩欧的形式,求$a$在$\bmod p$意义下的乘法逆元(改字母防止混淆)

$a \cdot a_{inv} \equiv 1(\bmod p)$

令 $a_{inv}$ 为扩欧的一组解,式子可以表示为$a \cdot a_{inv} + p \cdot y=gcd(a,p)$

因为$a$,$p$互质,所以$gcd(a,p)=1$,所以:

$a \cdot a_{inv} + p \cdot y=1=gcd(a,p)$

int exgcd(int a,int b,int &x,int &y){
	if(!b){x=1,y=0;return a;}
	int r=exgcd(b,a%b,x,y);
	int t=x; x=y; y=t-a/b*y;
	return r;
}
int get(int a,int p){
    int x,y;int ret=exgcd(a,p,x,y);
    if(ret==1) return (x%p+p)%p;//防止出现负数
    else return -1; 
}

 Ⅲ.线性求逆元

前面两种有点慢,毕竟每个数都求了一遍逆元,复杂度是$log$级的。

如何求 $\left[ 1,n \right]$在$\bmod p$意义下的逆元?

保证$p$为质数,且$p>n$

对于一个数 $x$ ,由于 $p>x$ ,设$p=kx+r$,$k=\left[ \frac{p}{x} \right]$,$r= p \bmod x$。

在$\bmod p$ 意义下:

$kx+r \equiv 0(\bmod p)$

$kx \equiv -r(\bmod p)$

$k \cdot x \cdot r_{inv } \equiv -1 \equiv -x \cdot x_{inv }(mod p)$

$x_{inv }= -r_{inv } \cdot k(\bmod p)$

因为$r= p \bmod x < x$,如果我们按顺序依次求逆元,则 $r_{inv }$ 一定比 $x_{inv }$先求出。

若按上等式处理,得出的结果是负数,我们可以先$+p $ 再 $\bmod p$.

int inv[MAXN];
void init(){ inv[1]=1;
     for(int i=2;i<=n;i++){
	inv[i]=-(p/i)*inv[p%i];
	inv[i]=(inv[i]%p+p)%p;
     }
}

练习:

P3811 【模板】乘法逆元