[数学/数论] 普通求逆

网上的求逆方法普遍长这样

a[1]=1;
for(int i=2;i<=n;++i) a[i]=(mod-(mod/i))%mod*a[mod%i]%mod;

下面介绍一种简单且万能的

pr[1]=1;
for(int i=2;i<=n;++i) pr[i]=pr[i-1]i%mod;
b[n]=qpow(pr[n],mod-2);
for(int i=n-1;i;–i) b[i]=b[i+1]
(i+1)%mod;
b[1]=1;
for(int i=2;i<=n;++i) b[i]=b[i]*pr[i-1]%mod;

讲解开始

逆元的定义

( m o d p ) \pmod p (modp)意义下, i × i − 1 ≡ 1 i\times i^{-1}\equiv1 i×i11,则 i i i i − 1 i^{-1} i1互为逆元

使用逆元的意义:为了保证精度,维护整数问题(即数论问题)的过程中,不能除,于是利用与原数积在模意义下为1的数,来替代除法

a n = n a_n=n an=n的逆元求法

常用,但是常数有点大

推导:
模 p 意 义 下 , 求 i 的 逆 元 p = k i + r ( k = ⌊ p i ⌋ , r = p   m o d   i ) k i + r ≡ 0 ( m o d p ) i − 1 r − 1 ( k i + r ) ≡ 0 ( m o d p ) i − 1 + k r − 1 ≡ 0 ( m o d p ) i − 1 ≡ − k r − 1 ( m o d p ) 由 于 r = p   m o d   i , 则 r < i , 求 i 时 r 已 求 出 , 可 以 递 归 求 解 边 界 1 − 1 = 1 \begin{aligned} &模p意义下,求i的逆元\\ &p=ki+r\quad(k=\lfloor\frac{p}{i}\rfloor,r=p\bmod i)\\ &ki+r\equiv 0\pmod p\\ &i^{-1}r^{-1}(ki+r)\equiv 0\pmod p\\ &i^{-1}+kr^{-1}\equiv 0\pmod p\\ &i^{-1}\equiv -kr^{-1}\pmod p\\ &由于r=p\bmod i,则r<i,求i时r已求出,可以递归求解\\ &边界1^{-1}=1 \end{aligned} p,ip=ki+r(k=ip,r=pmodi)ki+r0(modp)i1r1(ki+r)0(modp)i1+kr10(modp)i1kr1(modp)r=pmodi,r<i,ir,11=1

Code

a[1]=1;
for(int i=2;i<=n;++i) a[i]=(mod-(mod/i))%mod*a[mod%i]%mod;

任意数列的逆元求法

常数又小,适用范围又广
不学他学谁?

推导
对 于 { a n } ( 通 常 是 a n = n 的 数 列 ) , 记 p r i = ∏ j = 1 i a j , 第 一 遍 , i n v n = p r n p − 2 ( 即 p r n 的 逆 元 ) ≡ 1 ∏ i = 1 n a i i n v i = i n v i + 1 × a i + 1 , 递 推 下 去 第 二 遍 , i n v i = i n v i × p r i − 1 时 间 复 杂 度 O ( N ) \begin{aligned} &对于\{a_n\}(通常是a_n=n的数列),记pr_i=\prod_{j=1}^ia_j,\\ &第一遍,inv_n=pr_n^{p-2}(即pr_n的逆元)\equiv\frac{1}{\prod_{i=1}^na_i}\\ &inv_i=inv_{i+1}\times a_{i+1},递推下去\\ &第二遍,inv_i=inv_i\times pr_{i-1} \\\\&时间复杂度O(N) \end{aligned} {an}(an=n),pri=j=1iaj,,invn=prnp2(prn)i=1nai1invi=invi+1×ai+1,,invi=invi×pri1O(N)

Code

pr[1]=1;
for(int i=2;i<=n;++i) pr[i]=pr[i-1]*i%mod;
b[n]=qpow(pr[n],mod-2);
for(int i=n-1;i;--i) b[i]=b[i+1]*(i+1)%mod;
b[1]=1;
for(int i=2;i<=n;++i) b[i]=b[i]*pr[i-1]%mod;

Tips

  1. 注意边界:
    法一中inv[1]要赋初值
    法二中最后一层循环由于pr[0]=0,无法更新inv[1],那么手动赋1
  2. 注意求逆元的范围
    想清楚就行了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值