乘法逆元(学习笔记)

蒟蒻最近碰到了好多对分数取模的题,一脸懵逼(模不是只有整数之间才有的运算么)

定义

若整数b,m互质,并且b整除a(a被b整除,即a是b的整数倍),则存在一个整数x,使得\(a/b≡a*x\)(mod m),则称x为b的模m的乘法逆元,记为\(b^{-1}\)(mod m);

推理:

因为\(a/b=a*b^{-1}=a/b*b*b^{-1}\)

所以\(a/b≡a*b^{-1}≡a/b*b*b^{-1}\)(mod m)

所以\(b*b^{-1}≡1\)(mod m)

求法

其实求乘法逆元的方法有很多,就看哪种好用,注意别搞混了就行;

方法一 扩展欧几里得

\(a*x≡1\)(mod p)可以等价的转化为\(a*x-p*y=1\)

然后套用exgcd模板解方程,并检查gcd(a,p)是否等于1.

如果gcd(a,p)=1,把x调整到1~p−1的范围内即可.

ll exgcd(ll a,ll b,LL &x,LL &y) {
    if(b==0){x=1;y=0;return a;}
    ll GCD=exgcd(b,a%b,x,y);
    ll z=x;
    x=y;y=z-a/b*y;
    return GCD;
}//这个函数是扩展欧几里得算法的模板
ll Exgcd(ll a,ll mod){
    ll x,y;
    ll d=exgcd(a,mod,x,y);
    if(d==1) return(x%mod+mod)%mod;
    return -1;
}

方法二 费马小定理

如果p是质数,并且b<p,根据费马小定理(若p是质数,则对于任意正整数b,有\(b^p≡b\)(mod p))可得\(b^{p-1}≡1\)(mod p),相当于\(b*b^{p-2}≡1\)(mod p),所以,当模数p为质数时,\(b^{p-2}\)就是b的乘法逆元;

但如果只是保证b,p互质,那么乘法逆元可通过求解同余方程\(b*x≡1\)(mod p)得到;

ll feima(ll a,ll mod){
    return quickpow(a,mod-2,mod);
} //quickpow快速幂模板我就不讲了啊

方法三 欧拉定理

\(a^{φ(p)}≡1\)(mod p)得\(a^{φ(p)-1}\)是a的逆元

太懒,在这里不讲欧拉函数和欧拉定理了

https://www.cnblogs.com/PPXppx/p/9877833.html

方法四 递推

通过线性递推我们可以在O(N)的时间内求出1~n在模p意义下的乘法逆元;

以上几种方法可能在求某一个值的乘法逆元时很方便,但如果要求1~n中的每一个数的乘法逆元,就不得不用到这个递推了;

这里直接给出递推公式,反正我这么蒻,也不会证明,也不会理解,就直接背公式了;

void ditui(ll mod){
    inv[1]=1;
    for(int i=2;i<=n;i++) {
		inv[i]=(mod-mod/i)*inv[mod%i]%mod;
    }
}

扩展:做组合数学时,我们会要求阶乘的逆元,也可以在O(N)的时间递推;

jc[0]=1;
for(int i=1;i<=N;i++) 
    jc[i]=(jc[i-1]*i)%mod; 
inv_jc[N]=quickpow(jc[N],mod-2);
for(int i=N-1;i>=0;i--) 
    inv_jc[i]=(inv_jc[i+1]*(i+1))%mod;

posted on 2018-11-01 14:59  PPXppx  阅读(163)  评论(0编辑  收藏  举报