模意义下的乘法逆元

逆元定义

如果 a x ≡ 1 ( m o d p ) ax\equiv 1\pmod p ax1(modp),则称 x x x a a a 在模 p p p​ 意义下的乘法逆元。

逆元存在当且仅当 a ⊥ p a\perp p ap,即 gcd ⁡ ( a , p ) = 1 \gcd(a,p)=1 gcd(a,p)=1​。

a x ≡ 1 ( m o d p ) ax\equiv 1\pmod p ax1(modp) 转化可得 x ≡ 1 a ( m o d p ) x\equiv\dfrac{1}{a}\pmod p xa1(modp),那么模意义下 t ÷ a t \div a t÷a 就相当于 t × x t \times x t×x

快速求单个数的逆元

快速幂
费马小定理

p ∤ a p\not\mid a pa p ∈ P p\in\mathbb{P} pP 时,有
a p − 1 ≡ 1 ( m o d p ) a^{p-1}\equiv 1\pmod p ap11(modp)

由此转化可得 a × a p − 2 ≡ 1 ( m o d p ) a\times a^{p-2}\equiv 1\pmod p a×ap21(modp),此时就可以发现 a p − 2 a^{p-2} ap2 即为 a a a 在模 p p p 意义下的乘法逆元。

此时可以用快速幂计算逆元,时间复杂度 O ( log ⁡ p ) O(\log p) O(logp)

扩展欧几里得算法

Exgcd \text{Exgcd} Exgcd 也可以用于求逆元。

由裴蜀定理可知,若 a ⊥ p a\perp p ap,则必然 ∃   y \exist\, y y,使得 a × x + p × y = 1 a\times x+p\times y=1 a×x+p×y=1​ 成立。

容易发现, a × x + p × y = 1 ⇔ a × x ≡ 1 ( m o d p ) a\times x+p\times y=1\Leftrightarrow a\times x\equiv 1\pmod p a×x+p×y=1a×x1(modp)

使用 exgcd \text{exgcd} exgcd 解出这个方程即可,时间复杂度 O ( log ⁡ p ) O(\log p) O(logp)

线性求 1 ∼ n 1\sim n 1n​ 的逆元

例题:loj #110. 乘法逆元


现要求在 O ( n ) O(n) O(n) 的时间内,求出模 m m m 的意义下, [ 1 , m ) [1,m) [1,m) 中所有数的乘法逆元。

容易发现, ∀   m ∈ Z \forall\, m\in\mathbb{Z} mZ,有 1 × 1 ≡ 1 ( m o d m ) 1 \times 1 \equiv 1\pmod m 1×11(modm),所以 1 1 1 的逆元恒为 1 1 1

考虑 递推

假设我们已知 [ 1 , x ) [1,x) [1,x) 内所有数的逆元,需要求出 x x x 的逆元。

将模数 m m m 表示为 k x + t kx+t kx+t,其中 k = ⌊ m x ⌋ k=\Big\lfloor\dfrac{m}{x}\Big\rfloor k=xm t = m   m o d   x t=m\bmod x t=mmodx

由此可得 k x + t ≡ 0 ( m o d m ) kx+t\equiv 0\pmod m kx+t0(modm)

两边同乘 x − 1 × t − 1 ( m o d m ) x^{-1}\times t^{-1}\pmod m x1×t1(modm),可得

k x × x − 1 × t − 1 + t × x − 1 × t − 1 ≡ 0 ( m o d m ) k × t − 1 + x − 1 ≡ 0 ( m o d m ) \begin{aligned} kx\times x^{-1}\times t^{-1}+t\times x^{-1}\times t^{-1}\equiv 0\pmod m\\ k\times t^{-1}+x^{-1}\equiv 0\pmod m\\ \end{aligned} kx×x1×t1+t×x1×t10(modm)k×t1+x10(modm)

即可得 x − 1 ≡ k × t − 1 ( m o d m ) x^{-1}\equiv k\times t^{-1}\pmod m x1k×t1(modm)​。

在此基础上代入 k = ⌊ m x ⌋ k=\Big\lfloor\dfrac{m}{x}\Big\rfloor k=xm t = m   m o d   x t=m\bmod x t=mmodx,可得
x − 1 ≡ − ⌊ m x ⌋ ( m   m o d   x ) − 1 ( m o d m ) x^{-1} \equiv -\Big\lfloor\dfrac{m}{x}\Big\rfloor(m\bmod x)^{-1}\pmod m x1xm(mmodx)1(modm)
由于 ( m   m o d   x ) − 1 ∈ [ 1 , x ) (m\bmod x)^{-1}\in[1,x) (mmodx)1[1,x),所以 ( m   m o d   x ) − 1 (m\bmod x)^{-1} (mmodx)1​ 已知,线性递推即可。

  • PS   1 \textbf{PS 1} PS 1:当 m   m o d   x = 0 m\bmod x=0 mmodx=0 x x x 不存在模 m m m 意义下的乘法逆元。
  • PS   2 \textbf{PS 2} PS 2:由于 C++ \text{C++} C++ 中负数取模的结果为负数,所以在实际实现时递推式应写为 (m - m / x) * inv[m % x] % m

综上所述,递推式即为:
x − 1 = { 1 x = 1 − ⌊ m x ⌋ ( m   m o d   x ) − 1 x ≠ 1 ( m o d m ) x^{-1}= \begin{cases} 1&x=1\\ -\Big\lfloor\dfrac{m}{x}\Big\rfloor(m\bmod x)^{-1}&x\not=1 \end{cases} \pmod m x1={1xm(mmodx)1x=1x=1(modm)
线性递推即可在 O ( n ) O(n) O(n) 的时间内完成。

线性求任意 n n n 个数的逆元

例题:loj #161 乘法逆元 2


显然,对于每一个数用 快速幂 / exgcd \text{exgcd} exgcd 求解,时间复杂度为 O ( n log ⁡ p ) O(n\log p) O(nlogp),无法通过本题。

考虑使用前缀积 { s n } \{s_n\} {sn},其中 s i s_i si 记录 ∏ j = 1 i a j \prod_{j=1}^{i}a_j j=1iaj​​。

此外需要前缀积的逆元,使用 { t n } \{t_n\} {tn} 序列,其中 t i = s i − 1 ( m o d p ) t_i=s_{i}^{-1}\pmod p ti=si1(modp)

接下来可以通过 快速幂 / exgcd \text{exgcd} exgcd 求解 s n s_n sn 的逆元,记为 t n t_n tn​​。

接下来可以通过如下公式线性递推求出 { t n } \{t_n\} {tn}
t i ≡ s i − 1 ≡ 1 ∏ j = 1 i a j ≡ a i + 1 ∏ j = 1 i + 1 a j ≡ a i + 1 × s i + 1 − 1 ≡ a i + 1 × t i + 1 ( m o d p ) t_i \equiv s_i^{-1} \equiv \dfrac{1}{\prod_{j=1}^{i}a_j} \equiv \dfrac{a_{i+1}}{\prod_{j=1}^{i+1}{a_j}} \equiv a_{i+1}\times s_{i+1}^{-1} \equiv a_{i+1}\times t_{i+1}\pmod p tisi1j=1iaj1j=1i+1ajai+1ai+1×si+11ai+1×ti+1(modp)
记原序列的逆元为 { inv n } \{\text{inv}_n\} {invn},其中 inv i = a i − 1 ( m o d p ) \text{inv}_i=a_{i}^{-1}\pmod p invi=ai1(modp)

由于已知前缀积数组的逆元,那么
inv i ≡ a i − 1 ≡ 1 a i ≡ 1 s i s i − 1 ≡ s i − 1 s i ≡ s i − 1 × t i \text{inv}_i \equiv a_{i}^{-1} \equiv \dfrac{1}{a_i} \equiv \dfrac{1}{\dfrac{s_i}{s_{i-1}}} \equiv \dfrac{s_{i-1}}{s_i} \equiv s_{i-1}\times t_{i} inviai1ai1si1si1sisi1si1×ti
故递推即可,时间复杂度为 O ( n + log ⁡ p ) O(n+\log p) O(n+logp),其中 O ( log ⁡ p ) O(\log p) O(logp) 是求 s n s_n sn 逆元的复杂度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值