6.2.1 乘法逆元
乘法逆元
乘法逆元的定义
若 \(a\times x \equiv 1 ( \bmod b )\) ,且 \(gcd(a,b) = 1\) ,那么我们定义 \(x\) 为 \(a\) 在 \(\bmod b\) 意义下的逆元
对于在 \(\bmod b\) 下的运算,除 \(a\) 要用乘 \(x\) 来代替
扩展欧几里得
条件:\(gcd(a,p)=1\)
根据逆元定义 \(ax \equiv 1\ (\bmod p)\) 可得 \(ax + py = 1\) ,我们的目标是找到一组整数解 \(x,y\) 使得其成立
因为 \(gcd(p, a \bmod p) = gcd(a,p)= 1\)
所以我们可以递归去找到一组整数解 \(x',y'\) 使得 \(gcd(p, a \bmod p)=1\) 成立
单次时间复杂度: \(O(\log n)\)
费马小定理
条件:\(p \in pri\) 且 \(gcd(a,p)=1\)
根据费马小定理变形得:\(a \times a^{p-2} \equiv 1 \ (\bmod p)\)
inv[x] = pw(x, mod - 2)
单次时间复杂度: \(O(\log n)\)
线性递推求 \(1 \sim n\) 的逆元
给定 \(n, p\) 求 \(1 \sim n\) 在模 \(p\) 意义下的乘法逆元。
\(1 \le n \le 3e6,n < p < 20000528\) ,保证 \(p\) 是质数
这个如果再用上面两个算法的时间复杂度为 \(O(n \log n)\) ,是不能接受的
所以我们需要 \(O(n)\) 算法:线性递推
首先我们知道 \(1 \times 1^{-1} = 1 ( \bmod p)\) ,\(inv[1] = 1\)
设 \(k = \lfloor p/i \rfloor \ ,\ j = p \bmod i\) ,那么我们能得到 \(ki+j \equiv 0 \ (\bmod p)\)
两边同使乘 \(i^{-1}j^{-1}\) ,得到 \(kj^{-1}+i^{-1} \equiv 0\ (\bmod p)\)
所以 \(i^{-1} \equiv -kj^{-1} \ ( \bmod p )\)
inv[i] = mod - mod / i * inv[mod % i]
线性递推求 \(1 \sim n\) 阶乘的逆元
我们可以先将阶乘数组 fac[]
求出来,然后求出 \(fac[n]\) 的逆元 \(inv[n]\)
\(inv[n]\ 等价于 \ \frac {1} {n!}\)
\(inv[i - 1] = inv[i] * i\)