1. 程式人生 > 其它 >乘法逆元學習筆記

乘法逆元學習筆記

定義

\(a,b\) 滿足 \(ab \equiv 1\pmod p\)\(a,b\) 互為 \(\pmod p\) 的乘法逆元,也記作 \(a^{-1}\)\(b^{-1}\)

前置知識

1.費馬小定理

\(p\) 為質數且 \(\gcd(a,p) = 1\) ,則 \(a, p\) 滿足 \(a^{p-1}\equiv 1 \pmod p\)

證明:

考慮下面兩個整數序列:

\[1,2,3,4,5......p-2,p-1 \] \[a,2a,3a,4a,5a.......(p-2)a,(p-1)a \]

第一個序列很明顯每個數對 \(p\) 取餘各不相同,且為 \(1\)

\(p-1\)

對於第二個序列,如果有兩個不同的數 \(ax\)\(ay\) 使得 \(ax\equiv ay \pmod p\) ,則 \(p|a|x-y|\)

\(\because\) \(\gcd(a,p)=1\) , \(\therefore\) \(p||x-y|\)

\(\because\) \(x,y < p\)\(x \not= y\)\(\therefore\) \(0<|x-y|<p\)\(p \not| \,|x-y|\) ,矛盾。

\(\therefore\) 第二個序列每個數對 \(p\) 取餘都不相同, 且不為 \(0\)

\(\therefore\) 第二個序列中 \(p-1\) 個數對 \(p\) 取模為 \(1\)\(p-1\) 各一個。

現在把第一個序列的數和第二個序列的數各自相乘,得到:

\[(p-1)!\equiv a^{p-1}(p-1)! \pmod p \]

\(\because\) \((p-1)!\)\(p\) 互質。\(\therefore\) 可以把兩邊同時除以 \((p-1)!\) 得到:

\[a^{p-1}\equiv 1\pmod p \]

得證。

2.尤拉定理

\(a,p\) 滿足 \(\gcd(a,p)=1\) ,則 \(a^{\phi(p)}\equiv 1 \pmod p\)

。當 \(p\) 是質數時,尤拉定理等價與費馬小定理。

證明:

與上面類似,考慮下面兩個整數序列:

\[x_1,x_2,x_3,x_4,x_5......x_{\phi(p)-1},x_{\phi(p)} \] \[ax_1,ax_2,ax_3,ax_4,ax_5.......ax_{\phi(p)-1},ax_{\phi(p)} \]

第一個序列是模 \(p\) 意義下的一個簡化剩餘系,則第二個序列也為模 \(p\) 意義下的一個簡化剩餘系,把兩個序列的數各自相乘得到:

\[\prod_{i=1}^{\phi(p)}x_i\equiv a^{\phi(p)} \times \prod_{i=1}^{\phi(p)}x_i \pmod p \]

\(\because\) \(\prod_{i=1}^{\phi(p)}x_i\)\(p\) 互質。\(\therefore\) 可以把兩邊同時除以 \((p-1)!\) 得到:

\[a^{\phi(p)}\equiv1\pmod p \]

得證。

如何求逆元

我們現在要求 \(a\)\(\bmod \,p\) 意義下的逆元,即方程 \(ax\equiv 1 \pmod p\) 的解。

1.當 \(p\) 是質數且 \(\gcd(a,p)=1\) 時,根據費馬小定理可得:

\[a^{p-1}\equiv 1 \pmod p \] \[a \times a^{p-2} \equiv 1\pmod p \]

\(\therefore\) \(a\) 的逆元就是 \(a^{p-2}\) ,可以用快速冪求,時間複雜度 \(O(\log p)\)

2.當 \(\gcd(a,p)=1\) 時,根據尤拉定理可得:

\[a^{\phi(p)}\equiv 1 \pmod p \] \[a \times a^{\phi(p)-1} \equiv 1\pmod p \]

\(\therefore\) \(a\) 的逆元就是 \(a^{\phi(p)-1}\),其中尤拉函式 \(\phi\) 可以在 \(O(\sqrt p)\) 的時間算出來(不過好像也有一些玄學的演算法,但 \(p\) 的範圍一般不會爆 int ,所以這也夠了), 而快速冪的時間是 \(O(\log p)\)

逆元的作用

我們知道,餘數有可加性,可減性,可乘性,但沒有可除性,當要對分數取模時,逆元就派上用場。

分數 \(\dfrac{a}{b}\)\(p\) 取模的結果相當於 \(a \times b^{-1}\pmod p\) ,也就是分子乘上分母在模 \(p\) 意義下的逆元,這樣就可以對分數取模了。

注意,求逆元的時間複雜度是 \(O(\log p)\) ,所以求逆元的次數越少越好。

線性求逆元

有時候我們需要以 \(O(n)\) 的複雜度求出 \(1\)\(n\) 所有數在模 \(p\) 意義下的逆元,這時候一個一個求的複雜度就變為 \(O(n \log p)\) 了,我們需要用別的方法 \(O(n)\) 的求逆元。

P3811 【模板】乘法逆元 為例

題目要求求出 \(1\)\(n\) 所有數在模 \(p\) 意義下的逆元,我們考慮如何遞推逆元。

設我們當前正在求 \(a\) 的逆元,並且已經求出 \(1\)\(a-1\) 的逆元,現在要以 \(O(1)\) 的時間複雜度推出 \(a\) 的逆元。我們可以做一個帶餘除法:

\[p \div a = b ......r \]

變成等式:

\[a \times b + r = p \]

這個式子在模 \(p\) 意義下變為:

\[a \times b + r \equiv 0 \pmod p \]

\(r < a\) ,所以我們已經知道 \(r^{-1}\) ,現在我們給式子乘上一個 \(a^{-1}r^{-1}\)

\[a \times b \times a^{-1} \times r ^{-1} + r \times r^{-1} \times a^{-1}\ \equiv 0 \pmod p \]

\(a\)\(a^{-1}\)\(r\)\(r^{-1}\) 相乘都變成 \(1\) ,所以:

\[b \times r^{-1} + a^{-1} \equiv 0 \pmod p \] \[a^{-1} \equiv -b \times r^{-1} \pmod p \]

這樣我們就推出了 \(a\) 的逆元,總時間複雜度 \(O(n)\)

階乘逆元

組合數的公式是 \(C_n^m = \frac{n!}{m!(n-m)!}\) ,當我們需要對一個組合數取模,必須先把組合數算出來再取模,而算的過程中是無法取模的,但階乘又很大,所以我們就需要用到階乘的逆元。階乘的逆元也可以 \(O(n)\) 的遞推,但是是倒著推。

設我們當前正在求 \(k!\) 的逆元,已經求出了 \((k+1)!\)\(n!\) 的逆元,我們知道:

\[(k+1)![(k+1)!]^{-1} \equiv 1 \pmod p \]

\((k+1)!\) 拆成 \(k!\)\((k+1)\),可得:

\[k! \times (k+1)[(k+1)!]^{-1}\equiv 1 \pmod p \]

\(\therefore\) \((k!)^{-1}=(k+1)[(k+1)!]^{-1}\) ,然後我們就可以 \(O(n)\) 的遞推了,但是首先我們要求出 \(n!\) ,這就可以用費馬小定理或者尤拉定理直接求即可。

一些題目

P5431 【模板】乘法逆元 2

題意:給你 \(3\) 個數 \(n,p,k\) 和一個長度為 \(n\) 序列 \(a\) ,求出
\(\sum_{i=1}^n\frac{k^i}{a_i}\)
\(p\) 取模的值。

思路

樸素的求每一項的值時間複雜度是 \(O(n \log p)\) 的,而 \(n,p\) 都很大,而且這題卡的很死,所以考慮如何優化。

為了減少求逆元的次數,我們可以直接通分,然後就變成了下面這個樣子:

\[\frac{\sum_{i=1}^{n}{(k^i\times\prod^{i-1}_{j=1}a_i\times\prod_{j=i+1}^na_i})}{\prod_{i=1}^na_i} \]

這樣我們就可以我們可以先計算出分子和分母,再求一次逆元即可。我們可以 \(O(n)\) 的求出 \(a\) 的字首積和字尾積以及 \(k\) 的冪次方,最後統計答案即可,時間複雜度 \(O(n + \log p)=O(n)\)