乘法逆元

先来看几个同余式:
1.(a+b)%p=(a%p+b%p)%p;
2. (a-b)%p=(a%p-b%p)%p;
3. (ab)%p=(a%pb%p)%p;
然而当变成除法的时候同余式便不对了即:(a/b)%p不等于(a%p/b%p)%p想要解决这个问题我们就可以把除法变成乘法,即变成(a%p*(1/b)%p)%p这样就正确了,那么这里%p情况下的1/b就是b的逆元。
理解了什么是逆元,那么就要解决怎么求逆元。
根据定义可得:(b*(b的逆元))%p==1,我们很快就可以联想到另一个式子费马小定理:当a与p互质时,a^(p-1)==1(%p),那么
a^(p-2)==1/a(%p),那么一个数a在模p情况下的逆元其实就是pow(a,p-2)%p.
代码:

#include <bits/stdc++.h>//普通乘法逆元(1/a=a^(p-2)%p)
using namespace std;
#define int long long
int n,m;
int ksm(int a,int k){
    int ans=1,cnt=a;
    while(k){
        if(k&1){
            ans=ans*cnt%m;
        }
        cnt=cnt*cnt%m;
        k>>=1;
    }
    return ans%m;
}
signed main(){
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        int t=ksm(i,m-2);
        cout<<t<<endl;
    }
    return 0;
}

还有一种一连串数字模p求逆元的情况存在递推式。
乘法逆元模板题
具体代码:

#include <bits/stdc++.h>//线性递推逆元
using namespace std;
#define ll long long
int n,p; int inv[3000005];//存对应下标逆元
signed main(){
    ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    scanf("%d %d",&n,&p); inv[1]=1; printf("%d\n",1);
    for(int i=2;i<=n;i++){
        inv[i]=(ll)(p-p/i)*inv[p%i]%p;
        printf("%d\n",inv[i]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值