除法求模中求逆元的两种方法
Posted maybe96
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了除法求模中求逆元的两种方法相关的知识,希望对你有一定的参考价值。
今天下午还是有点闲的,不想刷题,不想补题,突然想起昨天的training 3里I题涉及到除法取模的问题,就来总结一下
首先对于模运算来说,是没有对于除法的取模的(即没有(a/b)%mod==a%mod/b%mod),但是在很多题目中都涉及到除法取模,所以就必须要了解或者掌握,对于除法取模以(a/b)%mod来说,我们首先需要得到b的逆元,根据逆元的定理 对于正整数和,如果有,那么把这个同余方程中的最小正整数解叫做模的逆元。
然后就是求逆元的两种方法。
第一种方法就是比较普遍的,也是挺基础的,就是通过费马小定理来求,但是要求mod必须是素数(一般题目中都会是1e9+7)。
费马小定理 :假如a是整数,p是质数,则a,p显然互质(即两者只有一个公约数1),那么我们可以得到费马小定理的一个特例,即当p为质数时候, a^(p-1)≡1(mod p)。
即可以得到a*a^(p-1)=1(%M);
也是我们就可以将除法取模转化为乘法取模 (a/b)%mod==a*b^(mod-2)%mod,但是对于b^(mod-2)来说,也挺难算的,这里就需要用到快速幂。
最后贴上代码片段
const long long mod=1e9+7; long long power_mod(long long a, long long b, long long mod) { long long ans = 1; while (b) { if (b & 1) ans = ans * a % mod; a = a * a % mod; b >>= 1; } return ans; } a*power_mod(b,mod-2,mod)%mod
第二种方法就是通过拓展欧几里得算法求逆元
扩展欧几里得定理:对于不完全为 0 的非负整数 a,b,gcd(a,b)表示 a,b 的最大公约数,必然存在整数对 x,y ,使得 gcd(a,b)=ax+by。
对于乘法逆元来说 a*x≡1(mod m) 也就等价于 a*x + m*y ==1 即当gcd(a,m)==1时就有拓展欧几里得定理,即求解这个方程解出的x就是a的逆元。
void exgcd(int a, int b, int &x, int &y) { if(0 == b){ x = 1, y = 0; return ; } exgcd(b, a%b, x, y); int flag = x; x = y; y = flag - a/b * y; }
以上是关于除法求模中求逆元的两种方法的主要内容,如果未能解决你的问题,请参考以下文章