计算逆元的三种方法

计 算 逆 元 的 三 种 方 法 计算逆元的三种方法

一、首先是两种O(log)时间求单个数的逆元

我们要求 a a a在模 p p p意义下的逆元
其中 a a a是小于 p p p的正整数, p p p是一个素数

① 费马小定理:

由费马小定理 a p − 1 ≡ 1   ( m o d   p ) a^{p-1}≡1\ (mod\ p) ap11 (mod p)可以得到:
a ⋅ a p − 2 ≡ 1   ( m o d   p ) a\cdot a^{p-2}≡1\ (mod\ p) aap21 (mod p)
所以可以直接使用快速幂求出 a p − 2 a^{p-2} ap2即为 a a a在模 p p p意义下的逆元

② 扩展欧几里得:

先假设我们要求的 a a a在模 p p p意义下的逆元为 x x x
可以得到方程 a ⋅ x ≡ 1   ( m o d   p ) a\cdot x≡1\ (mod\ p) ax1 (mod p)
变成一般等式: a ⋅ x + p ⋅ y = 1 a\cdot x+p\cdot y=1 ax+py=1
现在要求的就是 x x x
p p p是素数,所以 g c d ( a , p ) = 1 gcd(a,p)=1 gcd(a,p)=1,可以使用扩展欧几里得计算得到 x x x

二、线性求逆元:

显然 1 − 1 = 1 1^{-1}=1 11=1
假设现在已经计算出 i i i之前的所有正整数的逆元
现在要求 i i i的逆元
先写出等式: i ⋅ k + r = p i\cdot k+r=p ik+r=p
变成模 p p p下的恒等式: i ⋅ k + r ≡ 0   ( m o d   p ) i\cdot k+r≡0\ (mod\ p) ik+r0 (mod p)
两边同乘 i − 1 ⋅ r − 1 i^{-1}\cdot r^{-1} i1r1得到: k ⋅ j − 1 + i − 1 ≡ 0   ( m o d   p ) k\cdot j^{-1}+i^{-1}≡0\ (mod\ p) kj1+i10 (mod p)
移相: i − 1 ≡ − k ⋅ j − 1   ( m o d   p ) i^{-1}≡-k\cdot j^{-1}\ (mod\ p) i1kj1 (mod p)
k k k j j j可以分别用 p / i p/i p/i p % i p\%i p%i来代替: i − 1 ≡ − ( p / i ) ⋅ ( p % i ) − 1   ( m o d   p ) i^{-1}≡-(p/i)\cdot (p\%i)^{-1}\ (mod\ p) i1(p/i)(p%i)1 (mod p)
取 正 数 : i − 1 = ( p − p / i ) ⋅ ( p % i ) − 1 % p 取正数:i^{-1}=(p-p/i)\cdot (p\%i)^{-1}\%p i1=(pp/i)(p%i)1%p
p % i < i p\%ip%i<i 所以 p % i p\%i p%i的逆元已经算出来了,右端项没有未知数。所以就可以 O ( n ) O(n) O(n)的时间内算出 1 − n 1-n 1n之内所有数的逆元了

inv[1] = 1;
for(int i = 1; i <= n; i++)
	inv[i] = (p-p/i)*inv[p%i]%p;

你可能感兴趣的:(数论)