乘法逆元 求解及應用
乘法逆元定義
假設a,x,b為整數,b>1,且有$ax \equiv 1(\mod b)$成立
那麽a,x互為膜b的逆元
通俗一些,即兩數乘積膜p等於1,則他們互為b的逆元
************************
逆元算法求解
擴展歐幾裏得
既然已有同余式$ax \equiv 1(\mod b)$
那麽我們可以將其轉化為$ax+by=1$
可以用擴展歐幾裏得算法求出其最小非負整數解即為a在膜b意義下的逆元
不會擴展歐幾裏得算法看這裏
擴展歐幾裏得 推導及應用
void exgcd(int a,int b,int &x,int &y) { if(b==0){x=1;y=0;return a;} int gcd=exgcd(b,a%b,x,y); int tp=x; x=y; y=tp-a/b*y; return gcd; } int x,y; exgcd(a,b,x,y); inv=(x%b+b)%b;
該算法對於b是否為素數無限制
單次逆元的計算效率不錯
****************
費馬小定理
若 p 為素數, a為正整數,且a,p互質,則有$a^{p-1}\equiv1(\mod p)$
對於$a^{p-1}\equiv1(\mod p)$
我們變形為$a*a^{p-2}\equiv1(\mod p)$
那麽$x=a^{p-2}$%$p$即為我們所要求的逆元
該算法可直接用快速冪計算
復雜度為log級別,效率高
但不支持計算p不為素數的情況
***************************************
線性算法
首先有$1^{-1}≡1(\mod p)$
設$p=ki+r$ $(r<i$, $1<i<p)$
再將這個式子放到膜 p意義下得 $k
兩邊同時乘上$i^{-1}$,$r^{-1}$得
$kr^{-1}+i^{-1}≡0(\mod p) $
$ i^{-1}≡-kr^{-1}(\mod p) $
$ i^{-1}≡-\lfloor p/i \rfloor*(p \mod i)^{-1}(\mod p)$
於是我們得到一個線性遞推算法
inv[1]=1;
for(int i=2;i<=n;++i)
inv[i]=(ll)(p-p/i)*inv[p%i]%p;
該算法復雜度O(n)
適用於需要求解一整組逆元的時候
*******************
逆元應用
對於(a/b)%p這樣的式子
顯然不適用取膜運算律
所以我們將其改為**(a*inv[b])%p**
好像也沒什麽其他神奇的用處了= =
乘法逆元 求解及應用