對於\(a,p,x \in \mathbb Z\),若\((a,p)=1\),且\(ax \equiv 1(mod\;p)\),則將\(x\)稱做\(a\)在模\(p\)意義下的逆元,記做\(x=a^{-1}\)。算法
\[ bx \equiv b/a(mod\;p) \]ui
咱們知道,同餘是不知足同除性的(除數與模數互質時除外),所以不能直接對除法進行取模。而這條性質,能夠將除法轉換爲乘法,從而能夠在過程當中取模。spa
下面給出此性質的證實:
\[ \begin{aligned} &\because ax \equiv 1(mod\;p)\\ &\therefore abx \equiv b(mod\;p)\\ 又&\because (a,p)=1\\ &\therefore bx \equiv b/a(mod\;p) \end{aligned} \]code
擴展歐幾里得算法能夠用來求\(ax+by=(a,b)\)這一方程的一組特解,而咱們所要求的是\(ax \equiv 1(mod\;p)\)的解。將原方程進行變形,咱們能夠獲得
\[ \begin{aligned} &\because ax \equiv 1(mod\;p)\\ &\therefore p \mid (ax-1)\\ &\therefore ax-1=-py(y \in \mathbb Z)\\ &\therefore ax+py=1 \end{aligned} \]
故使方程\(ax+py=1\)成立的\(x\)值即爲\(a\)的逆元。class
代碼以下:擴展
void exgcd(int a,int b,int &x,int &y) { if(!b) { x=1; y=0; return; } exgcd(b,a%b,x,y); int t=x; x=y; y=t-a/b*y; return; }
根據歐拉定理,對於\(a,p \in \mathbb Z\),若\((a,p)=1\),則有\(a^{\varphi (p)} \equiv 1(mod\;p)\),由此可得
\[ a \cdot a^{\varphi(p)-1} \equiv 1(mod\;p) \]
故\(a^{\varphi(p)-1}\)即爲\(a\)的逆元。gc
根據費馬小定理,對於\(a,p \in \mathbb Z\),若\(p\)爲素數,則有\(a^{p} \equiv a(mod\;p)\),di
特別地,當\((a,p)=1\)時,\(a^{p-1} \equiv 1(mod\;p)\),co
由此可得
\[ a \cdot a^{p-2} \equiv 1(mod\;p) \]
故\(a^{p-2}\)即爲\(a\)的逆元。display
對於\(1\le i < p,i \in \mathbb{Z}\),
\[ \begin{aligned} &設p=ki+t(k,t\in \mathbb{Z},0<t<i)\\ &\therefore k=p/i,t=p\%i,ki+t \equiv 0(mod\;p)\\ &\therefore ki \equiv -t(mod\;p)\\ &\therefore -kt^{-1} \cdot i \equiv 1(mod\;p)\\ \end{aligned} \]
故\(-kt^{-1}\)爲\(i\)的逆元,
由取值範圍能夠獲得若從\(1\)開始遞推,\(t^{-1}\)將比\(i^{-1}\)先進行計算,因此咱們能夠獲得遞推式
\[ i^{-1}= \begin{cases} 1 & \text{i=1}\\ -p/i*(p\%i)^{-1} & \text{1<i<p} \end{cases} \]
代碼以下:
inv[1]=1; for(int i=2;i<=n;++i) inv[i]=(p-p/i)*inv[p%i]%p;