乘法逆元模板:【洛谷 P3811】

链接:【luogu P3811】

这几天在做 ybtoj 的组合数学,经常要用到乘法逆元,就先去某谷上写了一会乘法逆元。

乘法逆元的定义:若 a ∗ x ≡ 1 ( m o d b ) a*x\equiv1 \pmod {b} ax1(modb),且a与b互质,那么我们就能定义: x 为 a 的逆元,记为 a − 1 a^{-1} a1
,所以我们也可以称 x 为 a    在   m o d   b a~~在\bmod b a  modb 意义下的倒数。

求解方法:

根据费马小定理,若p 为质数,a 是正整数,且 a,p互质,那么就有:
a ∗ x ≡ a p − 1 ( m o d p ) a*x \equiv a^{p-1} \pmod {p} axap1(modp)
x ≡ a p − 2 ( m o d p ) x \equiv a^{p-2} \pmod {p} xap2(modp)
使用快速幂即可。

然后现在我们要在线性时间内求出 1~n 的逆元。
首先我们知道 1 − 1 ≡ 1 ( m o d p ) 1^{-1} \equiv1 \pmod p 111(modp)
我们设 p = k ∗ i + r p=k*i+r p=ki+r
然后就有 k ∗ i + r ≡ 0 ( m o d p ) k*i+r \equiv0 \pmod p ki+r0(modp)
左后两边同时乘上 i − 1 , r − 1 i^{-1},r^{-1} i1,r1,有
k ∗ r − 1 + i − 1 ≡ 0 ( m o d p ) k*r^{-1}+i^{-1} \equiv0 \pmod p kr1+i10(modp) i − 1 ≡ − k ∗ r − 1 ( m o d p ) i^{-1}\equiv -k*r^{-1}\pmod p i1kr1(modp)
将右边两项分别转换,得
i − 1 ≡ − ⌊ p i ⌋ ∗ ( p   m o d   i ) − 1 ( m o d p ) i^{-1}\equiv -⌊\frac {p}{i}⌋*(p\bmod i)^{-1}\pmod p i1ip(pmodi)1(modp)
为了保持其为正数,加上一个 p 使其为正后再取模
最后的式子是 i − 1 ≡ ( p − ⌊ p i ⌋ ) ∗ ( p   m o d   i ) − 1 ( m o d p ) i^{-1}\equiv (p-⌊\frac {p}{i}⌋)*(p\bmod i)^{-1}\pmod p i1(pip)(pmodi)1(modp)
然后就可以递推求解了。
直接上代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#define r register
#define rep(i,x,y) for(r ll i=x;i<=y;++i)
#define per(i,x,y) for(r ll i=x;i>=y;--i)
using namespace std;
typedef long long ll;
const ll V=3*1e6+10;
ll n,p,inv[V]; 
int main()
{
	scanf("%lld%lld",&n,&p);
	inv[1]=1;
	printf("%lld\n",inv[1]); 
	rep(i,2,n)
	{
		inv[i]=(p-p/i)*inv[p%i]%p;
		printf("%lld\n",inv[i]);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值