通过求逆元的几种方式复习基础数论
逆元
若 \(ax=1\pmod p\),那么称 \(a\) 是 \(x\) 的逆元,显然 \(x\) 也是 \(a\) 的逆元。
两边同时除以 \(a\) 得到 \(x=\frac1a\pmod p\),可以写成 \(x=a^{-1}\pmod p\),这么看来,乘法逆元就是取模意义下的倒数啊。
若 \(p\) 为质数,\(0\) 没有逆元,\(1\) 的逆元是 \(1\),\(p-1\) 的逆元是 \(p-1\)。其他都是一对一对的逆元,证明可见「裴蜀定理」。
为啥 \(p-1=\frac1{p-1}\pmod p\) 呢?直观解释是负负得正 \(-1=\frac1{-1}\),另一种解释是 \(1=p^2-2p+1=(p-1)^2\pmod p\)。
暴力求解
\(ax=1\pmod p\) 是个线性同余方程。解 \(x\) 必然 \(\in[0,p-1]\),所以直接暴力寻找可能的 \(x\)。
单次复杂度 \(\mathcal O(p)\)。
费马小定理
前置条件:\(p\) 为质数。
求解 \(x\) 就是计算 \(a^{-1}\)。
根据费马小定理,若 \(p\) 为质数,则 \(a^{p-1}=1\pmod p\),将等式两边同时乘 \(a^{-1}\) 就可以得到 \(a^{p-2}=a^{-1}\),快速幂求解。
单次复杂度 \(\mathcal O(\log p)\)。
欧拉定理
费马小定理可以看作欧拉定理的特殊情况。
根据欧拉定理,若 \(\gcd(a,p)=1\),则 \(a^{\varphi(p)}=1\pmod p\),将等式两边同时乘 \(a^{-1}\) 就可以得到 \(a^{\varphi(p)-1}=a^{-1}\)。
单次复杂度由 \(\varphi\) 的求解方法确定,从 \(\mathcal O(\sqrt p)\sim\mathcal O(\log p)\) 均有可能。
拓展欧几里得
\(ax=1\pmod p\) 可以转化为 \(ax+pk=1\),其中 \(a,p\) 已知,需要求一组 \(x,k\) 使得 \(x\in[0,p-1]\)。
通过裴蜀定理可得存在一组 \(x,k\) 使得 \(ax+pk=\gcd(a,p)\)。所以若 \(\gcd(a,p)=1\),那么 \(ax+pk=1\) 必然有解。根据解的周期性可知必然存在一个解使得 \(x\in[0,p-1]\)。所以逆元存在的充分条件是 \(\gcd(a,p)=1\)。
求解 \(ax+pk=1\) 可以采用拓展欧几里得的方法求解。
前缀积
\(\binom nm=\frac{n!}{m!(n-m)!}\),类似的,\(\frac1a=\frac{(a-1)!}{a!}\)。
通过前缀积预处理出 \(1!,2!\ldots(a-1)!,a!\),求出 \(a!\) 的逆元 \(\frac1{a!}\),再一路循环回去 \(\frac1i=\frac{i+1}{(i+1)!}\) 就可以求出所有阶乘和阶乘的逆元。而且这个方法对于求 \(\frac1{\prod_{i=l}^ri},1\le l\le r<p\) 也是在常数时间内完成,
求出 \([1,n]\) 中所有逆元的复杂度是 \(\mathcal O(n+\log p)\)。
线性求逆元
发现要求出 \(\frac1a\) 必须得求出 \(\frac1{p\bmod a}\),可以使用数组递推下去也可以直接递归求解。
求出 \([1,n]\) 中所有逆元的复杂度是 \(\mathcal O(n)\)。
若递归求解,已知时间复杂度上界为 \(\mathcal O(n^{\frac13})\),下界为 \(\Omega(\frac{\ln n}{\ln\ln n})\)。有人猜想其复杂度为 \(\mathcal O(\log^2n)\)。不过在 int
范围内可以近似看作单 \(\log\) 倒是真的。
模数 \(p\) | \(998244353\) | \(10^9+7\) | \(10^9+9\) |
---|---|---|---|
\(n=10^6\) 的递归次数 | \(30\) | \(31\) | \(29\) |
\(n=10^7\) 的递归次数 | \(35\) | \(39\) | \(35\) |
\(n=10^8\) 的递归次数 | \(40\) | \(45\) | \(42\) |
线性筛
若 \(t\mid a\),那么 \(\frac1a=\frac1t\times\frac1{\frac at}\)。
借助线性筛筛出 \([1,n]\) 的所有质数以及他们的逆元。在线性筛时,每个数 \(i\) 只会被自己的最小质因子 \(\operatorname{mpf}(i)\) 筛到,所以计算 \(\frac1{\operatorname{mpf}(i)}\times\frac1{\frac i{\operatorname{mpf}(i)}}\) 就行了。
若求出 \([1,n]\) 中所有逆元,线性筛的复杂度为 \(\mathcal O(n)\),只有 \([1,n]\) 中的质数需要计算逆元,质数个数约为 \(\frac n{\ln n}\),每个的计算复杂度为 \(\log p\),所以总复杂度为 \(\mathcal O(n+\frac{n\log p}{\ln n})\),近似于线性。