论乘法逆元

1为什么要求逆元
有三个整数a,b,m,要求出(a/b)%m的值,该怎么求?
先考虑最简单的做法,直接除
这样做有什么缺点?
首先,c++中除法常数极大仅次于取模,为乘法的十几倍,容易被卡常数
然后,假设a和b都非常大,形如(a/b)%m的算法有没有同余运算公式,容易丢失精度造成答案错误,但是乘法有......
解释:现给出一个公式(a*b)%m=(a%m*b%m)%m
把其中的乘号改成加减都成立,就除号不成立,你说气不气......
除法实在是太鸡肋了,不想用了
于是,乘法逆元诞生了

2逆元是什么
初中数学告诉我们,a/b = a*(1/b)(b分之1) = b^-1(b的-1次方)(此处参考除以一个数等于乘以它的倒数)
那么,(1/b)和(b^-1)就是b模m的乘法逆元
那乘法逆元不就是倒数吗?
这么解释非常的不严谨,但是等会就严谨了
乘法逆元有一点不同于倒数,那就是上述内容建立在模m的意义下
也就是说:把b模m的逆元表示为inv(b)
则有(a/b)%m = (a*inv(b))%m
下面给出官方定义(取自acwing基础课)
若整数 b,m互质,并且对于任意的整数 a,如果满足 b|a,则存在一个整数 x,使得 a/b≡a×x(modm),则称 x为 b 的模 m乘法逆元,记为 b^−1(mod m)。
b存在乘法逆元的充要条件是 b 与模数 m 互质。
说的好,但是没听懂,怎么办?
对比刚才的定义,我们可以发现两点不同
一,要满足b|a,即a%b = 0,b是a的因数
这个显而易见了,b不能整除a都出分数了,指定不行
但是,如果把上面的除法改为c++的int除法(即向下取整)会直接满足b|a,所以这类除法向下取整,不考虑余数的问题,可无视此条件
二,b与m互质,网上有人用裴蜀定理证,根本看不懂
这里设p为b和m的最大公约数,即gcd(b,m),且p不等于1,设x为b的乘法逆元
根据上文”倒数“的定义得b*x≡1(modm)
根据模运算的定义,有b*x=k*m+1,这一步把modm提了出来
两边同时乘p得p*b*x=p*k*m+1,下一步可以移项提公因式了
所以p(b*x-k*m)=1
这里,由于乘法逆元只在正整数范围内讨论,p和(b*x-k*m)都只能等于1
与p不等于1冲突
p只能等于1,即b与m互质
一点没用裴蜀定理
至此,完成了倒数到乘法逆元的转化

3怎么求乘法逆元
p为质数的情况(即acwingyxc老师讲的)
利用费马小定理可得b模m的乘法逆元为b^m-2
可以用到快速幂
给出代码(c++)

#include<bits/stdc++.h>
using namespace std;
int n;
long long quick_pow(int a,int b,int p){
    long long ans=1,res=a;
    while(b!=0){
        if(b&1){
        	ans=ans*res%p;
		}
        res=res*res%p;
        b>>=1;
    }
    return ans;
}
int main(){
    cin>>n;
    while(n--){
        int a,b;
        scanf("%d%d",&a,&b);
        if(a%b==0){
        	puts("impossible");
		}else{
			printf("%lld\n",quick_pow(a,b-2,b));
		}
    }
    return 0;
}


4后记
本文缺失多种求逆元方式以及费马小定理的证明(因为作者不会),之后会补上的
本文如有不严谨请各位神犇指点
本文作者为senlinguyvan1,目前只在博客写文章,其他平台全为盗版

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值