逆元基本性质与运用

逆元

逆元,类似于倒数,
如果 a x ≡ 1 ( m o d p ) ax≡1 (mod p) ax1(modp),且 g c d ( a , p ) = 1 gcd(a,p)=1 gcd(a,p)=1(a与p互质),则称a关于模p的乘法逆元为x。
注意:只有a和p互质的时候,a才有关于p的逆元,所以当有多个p和a互质时,所求的a关于p的逆元也是不同的。

a ∗ x ≡ 1 ( m o d   p ) a*x ≡ 1 (mod \ p) ax1(mod p)

其中 x x x 叫做 a a a的关于 p p p的逆元,记为: i n v ( a ) = x inv(a) = x inv(a)=x
所以 a ∗ i n v ( a ) ≡ 1 ( m o d p ) a * inv(a) ≡ 1 (mod p) ainv(a)1(modp)

例如:

若a*x = 1那么x是a的倒数,x = 1/a
但是a如果不是1,那么x就是小数
那数论中,这个mod出来这里不能有小数,所以现在问题变了

我们可以这么写:

a / b = a / b ∗ b ∗ T a/b=a/b*b*T a/b=a/bbT (T为b的逆元,这里省略了mod操作,太懒了不想写 )
1 = b ∗ T 1=b*T 1=bT

但是如何去求逆元呢?我们引入一个定理:(邦邦卡邦~~~)

费马小定理(Fermat’s little theorem)是数论中的一个重要定理,在1636年提出,其内容为:
假如p是质数,且 g c d ( a , p ) = 1 gcd(a,p)=1 gcd(a,p)=1,那么 a ( p − 1 ) ≡ 1 ( m o d   p ) a^{(p-1)}≡1(mod\ p) a(p1)1(mod p)
即:假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。

接着继续:

a ( p − 1 ) = 1 ( m o d   p ) a^{(p-1)}=1(mod\ p) a(p1)=1(mod p)
a ∗ a ( p − 2 ) = 1 ( m o d   p ) a*a^{(p-2)}=1(mod\ p) aa(p2)=1(mod p)

哎,是不是很像上面那个式子
我们把它拿过来看看:

b ∗ T = 1 b*T=1 bT=1

哎,这么一对应
我们发现

b 的逆元即为 b ( p − 2 ) b的逆元即为b^{(p-2)} b的逆元即为b(p2)

线性求逆元

p = k ∗ i + j p=k*i+j p=ki+j

k ∗ i + j = 0   ( m o d   p ) k*i+j=0\ (mod\ p) ki+j=0 (mod p)

k ∗ i ∗ ( i − 1 ∗ j − 1 ) + r ∗ ( i − 1 ∗ j − 1 ) = 0   ( m o d   p ) k*i*(i^{-1}*j^{-1})+r*(i^{-1}*j^{-1})=0\ (mod\ p) ki(i1j1)+r(i1j1)=0 (mod p)
k ∗ j − 1 ∗ i − 1 = 0   ( m o d   p ) k*j^{-1}*i^{-1}=0\ (mod\ p) kj1i1=0 (mod p)

i − 1 = − k ∗ j − 1   ( m o d   p ) i^{-1}=-k*j^{-1}\ (mod\ p) i1=kj1 (mod p)
i − 1 = − ⌊ p / i ⌋ ∗ k ∗ j − 1   ( m o d   p ) i^{-1}=-\lfloor p/i \rfloor *k*j^{-1}\ (mod\ p) i1=p/ikj1 (mod p)

再代入 j = p   m o d   i j=p\ mod\ i j=p mod i,得
i − 1 = − ⌊ p / i ⌋ ∗ ( p   m o d   i ) − 1   ( m o d   p ) i^{-1}=-\lfloor p/i \rfloor *(p\ mod\ i)^{-1}\ (mod\ p) i1=p/i(p mod i)1 (mod p)

我们可以发现,这个 ( p   m o d   i ) (p\ mod\ i) (p mod i)是小于i的,也就是我们求过,所以我们可以用递推求出
也就是以下伪代码:

i n v [ i ] = − ⌊ p / i ⌋ ∗ i n v [ p   m o d   i ] inv[i]=-\lfloor p/i \rfloor *inv[p\ mod\ i] inv[i]=p/iinv[p mod i]

代码如下:

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

来看个例题吧

例题
AC代码:
请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值