乘法逆元(inverse element)及四大相关求法详解(含证明)
文章目錄
- 乘法逆元及四大相關求法詳解(含證明)
- 開胃菜
- 1. 定義及理解
- 1.1 乘法逆元的定義
- 1.1.1 極簡定義
- 1.1.2 詳細定義
- 1.1.3 理解及其相關證明<br>
- 2. 逆元的四大求解法
- 2.1 費馬小定理求逆元
- 2.1.1 何為費馬小定理
- 2.1.2 證明費馬小定理
- 2.1.3 代碼板子
- 2.2 擴展歐幾里得求逆元
- 2.2.1 何為歐幾里得算法
- 2.2.2 證明歐幾里得算法
- 2.2.3 擴展歐幾里得算法
- 2.2.4 推導擴展歐幾里得算法
- 2.2.5 代碼板子
- 2.3 線性遞推求逆元
- 2.3.1 何為線性遞推
- 2.3.2 推導線性遞推
- 2.3.3 代碼板子
- 2.4 歐拉定理求逆元
- 2.4.1 何為歐拉定理
- 2.4.2 證明歐拉定理
- 2.4.3 推導歐拉函數(shù)
- 2.4.4 代碼板子
- 3. 階乘逆元
乘法逆元及四大相關求法詳解(含證明)
知識的補缺是老生常談的一大問題,隨著自身學習進程的推進,越發(fā)覺著逆元知識的重要,故此我站在網(wǎng)上各路大牛的肩膀上,對此知識進行一定程度上的系統(tǒng)梳理。如有不足之處,還請大家指出,大家共同進步,互利共贏 !!
開胃菜
先呈上菜:
很明顯,上述式子只有一條不成立,即 ( a / b ) % m,但有些情況下,又需要進行有模運算的除法。由于式子不成立,當 a 過大或者 b 過大時,極易導致計算過程丟失精度,造成結果誤差。因此,為了避免這一遭,逆元就應運而生了。
1. 定義及理解
1.1 乘法逆元的定義
1.1.1 極簡定義
? 在 模m 有意義的條件下, 若 ax ≡ 1 ( mod m ), 則稱 a 關于 1 模 m的乘法逆元為 x
1.1.2 詳細定義
? 若整數(shù) a,m 互質(zhì),并且對于任意的整數(shù) b,如果滿足 a | b ( a 能整除 b ),則存在一個整數(shù) x,使得 b/a ≡ bx ( mod m ) ,則稱 x 為 a 模 m 的乘法逆元,記為 a?1a^{?1}a?1( mod m ) 或者 inv( a )。
1.1.3 理解及其相關證明
根據(jù)定義:模 m 意義下, a 如果有逆元 x,那么除以 a 相當于乘以 x
b / x1 = b * x1^-1 // 即 b / a = b * a^-1 ,基礎乘除轉換 inv[x1] ≡ x1^-1 ( mod m) // inv[x1] 即為 x1 在模 m 情況下的逆元 b / x1 ≡ b * inv[x1] ( mod m ) // 結論b / x1 ≡ b * inv[x1] ( mod m ) 等式成立證明:( inv[ x1 ] = x , 即 x1 的逆元為 x)
假設: b1 / x1 mod m = n (式子一) (式子一兩邊同時乘上 x1)b1 mod m = n * x1 mod m (式子二) (簡化式子二)b1 ≡ n * x1 ( mod m ) (式子三) (式子三兩邊同時乘上 x, x 為 1 / x1, 即假設 x 為 x1 的逆元) (根據(jù)定義式) x * x1 ≡ 1 ( mod m ) (式子四 ,因為 x 是 x1 的逆元,所以得出這個式子)b1 * x ≡ n * x1 * x ( mod m ) (式子三等式兩邊乘以 x -> 式子五) (式子四帶入式子五,有)b1 * x ≡ n * 1 ( mod m ) (式子六) (式子六化簡)b1 * x ≡ n ( mod m ) (式子七) (與式子七變形)b1 * x mod m = n mod m (式子七) (式子一帶入式子七)b1 * x mod m = b1 / x1 mod m mod m (式子八) (等式右邊模了一次 m 之后,值肯定比 m 小,因此第二次模 m 無意義,式子八簡化)b1 * x mod m = b1 / x1 mod m (結論) (x 是 x1 的逆元,式子三定義的) (證畢)注意\color{orange}注意注意
① 當且僅當 a 與 m 互質(zhì)時,a 關于 1 模 m 的 乘法逆元 有解。特別地,當模數(shù) m 為質(zhì)數(shù)時,am?2a^{m-2}am?2 即為 a 的乘法逆元。若不互質(zhì),則無解。
② 若 m 為素數(shù),則從 1 到 m-1 的任意數(shù)都與 m 互質(zhì),即在 1 到 m-1 之間都恰好有一個關于 1 模 m 的乘法逆元。
Q:\color{Red}Q:Q: 為什么當 a 與 m 互質(zhì)時,a 關于 1 模 m 的 乘法逆元 才有解 ???
首先介紹一下 裴蜀定理:
裴蜀定理\color{orange}裴蜀定理裴蜀定理
① 若 a, b 是整數(shù),且 gcd(a , b) = d,那么對于任意的整數(shù) x , y。ax+by 都一定是 d 的倍數(shù),特別地,一定存在整數(shù)x,y,使 ax+by = d成立。
② 推論:a ,b 互質(zhì)的充分必要條件是存在整數(shù) x , y 使得 ax+by = 1 。
我們可以知道
? a ? x ≡ 1( mod m)
? a ? x= 1?my
? ax + my= 1 (?1)(\ 1\ )(?1?)
裴蜀定理告訴我們,方程(1)當且僅當 gcd( a ,m) = 1時有解。也就是說,當且僅當 a 與 模數(shù)m 互質(zhì)時,存在 a 的乘法逆元。因此 大部分 有理數(shù)取模問題給定的模數(shù)都是質(zhì)數(shù),這樣能夠在 a mod m ≠ 0 的情況下保證存在 a 的逆元。
Q:\color{Red}Q:Q: 為什么當模數(shù) m 為質(zhì)數(shù)時,am?2a^{m-2}am?2 即為 a 的乘法逆元 ???
由費馬小定理可知:
當 m為質(zhì)數(shù)時,am?1a^{m?1}am?1 ≡ 1 ( mod m )
? ? a * am?2a^{m?2}am?2 ≡ 1 ( mod m )
則由逆元定義可知,此時 am?2a^{m?2}am?2為 a 的乘法逆元
2. 逆元的四大求解法
2.1 費馬小定理求逆元
2.1.1 何為費馬小定理
費馬小定理是數(shù)論中一個定理:
假如 a 是 一個整數(shù),m 是一個質(zhì)數(shù),那么
? ama^{m}am ≡ a ( mod m )
如果 m 是一個質(zhì)數(shù),而整數(shù) a 不是 m 的倍數(shù),那么
? am?1a^{m?1}am?1 ≡ 1 ( mod m )
2.1.2 證明費馬小定理
下面的證明,使用模運算,最初是由 James Ivory 在1806年發(fā)現(xiàn)的,后來被 Dirichlet 在1828年重新發(fā)現(xiàn)。
我們首先考慮整數(shù)a,2a,3a,…( p - 1 )a。這些數(shù)都不等于p對其他數(shù)的模,也不等于0。
如果這樣,那么有:r × a ≡ s × a ( mod p ),1 ≤ r < s ≤ p - 1,那么,兩邊消去a將得到
r ≡ s ( mod p ),這是不可能的,因為 r 和 s 都在 1 和 p - 1 之間。
因此,前一組整數(shù)必須同余模 p 到1,2,…p - 1。
把這些同余相乘,你會發(fā)現(xiàn):a × 2a × 3a × … × (p - 1) × a ≡ 1 × 2 × 3 × … × (p - 1) ( mod p)意味著a × (p - 1)! ≡ (p - 1)!(mod p)。
從這個表達式的兩邊消去(p - 1)!,我們便得到:ap?1a^{p-1}ap?1 ≡ 1 ( mod p )。
2.1.3 代碼板子
首先翻出我們之前準備好的結論:b / x1 mod m = b * x mod m (x 是 x1 在模 m 下的逆元) (式子一) 逆元定義:x1 * x ≡ 1 ( mod m ) (式子二) 我們把費馬小定理的結論帶入式子二,有x1 * x = x1^(p-1) (式子三) 故此x = x1^(p-2) (結論) ( 即 x1的 逆元 x 為 x1^(p-2) ) /* 快速冪· 求 a^k % m */ /* 求逆元 即為 quick_power( a , m-2 , m ) */int quick_power(int a,int k,int m) {int res=1;while(k){if(k&1) res= res*a % m;a= a*a % m;k>>=1;}return res; }費馬小定理局限性\color{Green}費馬小定理局限性費馬小定理局限性
必須滿足 m 要為質(zhì)數(shù) 的前提條件 ,才可求逆元
2.2 擴展歐幾里得求逆元
2.2.1 何為歐幾里得算法
歐幾里得算法又稱輾轉相除法,是指用于計算兩個非負整數(shù)a,b的最大公約數(shù)。
公式 :gcd( a,b ) = gcd( b,a mod b )
2.2.2 證明歐幾里得算法
2.2.3 擴展歐幾里得算法
由名字可知這是建立在歐幾里得算法上的一種算法,定義如下:
? 給一個線性方程 ax + by = m,給出 a,b,m 求解出相應的 x 和 y 。
注意\color{orange}注意注意
首先,只有 m % gcd( a,b) ==0 ,即 當且僅當 m 是 a,b 最大公約數(shù)的倍數(shù)時,該線性方程才有解。
當 m 為1 時,由裴蜀定理推論可知,只有當 a,b互質(zhì)才有解。
2.2.4 推導擴展歐幾里得算法
證:存在整數(shù)對( x,y )使得 ax + by = gcd( a,b )
證明:設 a > b 當 b = 0 時,a?1+b?0 = gcd( a,b ) = a,此時 x=1,y=0 當 b !=0 時, 設 a?x1 + b?y1 = gcd( a,b ) b?x2 + a%b?y2 = gcd( b,a%b ) 又由于gcd(a,b)=gcd( b,a%b )所以有 a?x1 + b?y1=b?x2 + a%b?y2 又因為 a%b = a ? ( a / b )?b , 得到 a?x1 + b?y1=a?y2 + b?x2 ? ( a / b )?b?y2 ? 即 x1=y2 ? y1=x2 ? (a/b)?y2因此可以遞歸的定義exgcd,同樣b=0時遞歸結束。返回最大公約數(shù)。
2.2.5 代碼板子
int exgcd( int a , int b , int &x , int &y ) {if( !b ) // 當 b =0 時{x=1,y=0;return a; }// 當 b!=0 時int d=exgcd( b, a%b, x, y );int t=x;x=y;y=t-(a/b)*y;return d; }怎么用拓展歐幾里得求逆元呢?
把 ax ≡ 1( mod m)稱為 a 關于 1 mod m 的乘法逆元。 它的解其實就相當于尋找方程 ax+my=1 的解。根據(jù)乘法逆元的性質(zhì),只有當 a 與 m 互質(zhì),a 關于模 m 的乘法逆元才有解。如果不互質(zhì),則無解。那么這個方程就是 a,m 互質(zhì)的充要條件是方程 ax+my = 1 必有整數(shù)解。
注意\color{orange}注意注意
我們知道了線性方程 ax + by = m 有整數(shù)解的條件,并且根據(jù)上述算法,也能求出一組方程的解。但是 這組解很可能包含負數(shù),當我們求逆元時需將其轉化為正數(shù),如下
/* 求逆元 a , m */ int Inv_a(int a,int m) {int x,int y;int d=exgcd(a,m,x,y);if(d==1){return ( x%m + m )%m; // 保證逆元為正數(shù)}elsereturn -1; // ax+my=1 不成立,即 a ,m 不互質(zhì),無解}2.3 線性遞推求逆元
2.3.1 何為線性遞推
exgcd和費馬小定理只適合用來求單個逆元,求3e6以內(nèi)所有的逆元在肯定會超時,此時用線性遞推求逆元可以保證時間復雜度在O( n )內(nèi)
2.3.2 推導線性遞推
設 t = m / i,k = m % i,有:m = i * t + k 即 i * t + k Ξ 0 ( mod m ) 即 k Ξ - i * t ( mod m ) 兩邊同時除以 i * k 有 1 / i Ξ - t / k ( mod m ) 將k,t帶入 有 inv[ i ] Ξ - m / i * inv[ m % i ] ( mod m ) 為防止有負數(shù),有inv[ i ] = ( m - m / i) * inv[ m % i ]) % m核心:inv[ i ] = ( m - m / i ) * inv[ m % i ] % m
2.3.3 代碼板子
long long inv[N];void get_inv( long long m ) {inv[1]=1;for(int i=2;i<=m-1;i++)inv[i]=( m-m/i )*inv[ m%i ]%m; }2.4 歐拉定理求逆元
2.4.1 何為歐拉定理
若a、m互質(zhì),則有 aφ(m)a^{φ( m)}aφ(m) ≡ 1 ( mod m ) ,φ( m)稱為歐拉函數(shù),表示1~m中與 m互質(zhì)的個數(shù)
2.4.2 證明歐拉定理
歐拉定理證明
把不超過𝑚且與𝑚互質(zhì)的正整數(shù)拿出來構成集合{ x1,x2,…,xφ(m)x_1,x_2,…,x_{φ(m)}x1?,x2?,…,xφ(m)?}
設𝑎與𝑚互質(zhì)且xi也與m互質(zhì),則( axia_{xi}axi?,m )=(m,axia_{xi}axi?%m) =1
集合{ ax1,ax2,…,axφ(m)ax_1,ax_2,…,ax_{φ(m)}ax1?,ax2?,…,axφ(m)?}在模𝑚意義下與前一集合相等 ( 都是與m互質(zhì)的集合 )(均為模m意義下模𝑚意義下的縮系)
將集合內(nèi)所有原數(shù)相乘,得到
ax1,ax2,…,axφ(m)ax_1,ax_2,…,ax_{φ(m)}ax1?,ax2?,…,axφ(m)? ≡ aφ(m)∏i?(m)xi≡∏i?(m)xia^{φ(m)}∏^{?(m)}_ixi≡∏^{?(m)}_ixiaφ(m)∏i?(m)?xi≡∏i?(m)?xi ( mod m )
因為 xi 與 m 互質(zhì),則都有逆元
對上個式子的右邊2個式子每個 xi 都乘上逆元
則 aφ(m)a^{φ(m)}aφ(m) ≡ 1 ( mod m )
證畢
2.4.3 推導歐拉函數(shù)
歐拉函數(shù)\color{orange}歐拉函數(shù)歐拉函數(shù)
?( m ) 為正整數(shù) m 與1,2,???,m?1,m互質(zhì)的個數(shù)
設 m = pa1pa2????pakp^{a1}p^{a2}????p^{ak}pa1pa2????pak
則 ?( m ) = (p1?1)p1a1?1×(p2?1)p2a2?2???×(pk?1)pkak?1(p_1?1)p_1^{a1?1}×(p_2?1)p_2^{a2?2}???×(p_k?1)p_k^{ak?1}(p1??1)p1a1?1?×(p2??1)p2a2?2????×(pk??1)pkak?1?
取自[逆元、歐拉定理 - I_N_V - 博客園 (cnblogs.com)]
2.4.4 代碼板子
int phi(int x) {int ans=x;for( int i=2 ; i*i<=x ; i++ )// 時間復雜度:O ( √n )if(x%i==0){ans = ans/i*(i-1); // 由 Φ(m)=m(1- 1 / pi)..得出 while(x%i==0) x/=i;// 除干凈質(zhì)因子}if(x>1)ans=ans/x*(x-1);// m有一個大于√m 的質(zhì)數(shù)return ans; }3. 階乘逆元
顧名思義,就是階層的逆元,即分母,既然這篇文章主要是以逆元為主題,那么順道提一下,希望有助于排列組合的計算,上板子!!
// 階乘逆元 typedef long long LL; const int N=1e6+5; LL fac[N]; //階乘 LL inv[N]; //逆元 // 求階乘 void get_fac() {fac[0] = inv[0] = 1;for (int i = 1 ; i <= 1000000 ; i++){fac[i] = fac[i-1] * i % m;inv[i] = quick_power(fac[i],m-2,m); //表示i的階乘的逆元 } }// 求組合數(shù) inline LL get_C( LL a, LL b ) // C(a,b) = a!/((a-b)!*b!) % mod {return fac[a] * inv[a-b] % m * inv[b] % m; }以上內(nèi)容尚未完全,隨著今后學習的推進,我會繼續(xù)對其進行補充與完善。另外,大家如果覺得我寫的還行的話,還請贈予我一個可愛的贊,你的贊對于我是莫大的支持。
總結
以上是生活随笔為你收集整理的乘法逆元(inverse element)及四大相关求法详解(含证明)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spark编程基础-(二)Scala语言
- 下一篇: C语言编译的五大过程详解