逆元定义
逆元和我们平时所说的倒数是有一定的区别的,我们平时所说的倒数是指:a*(1/a) = 1,那么逆元和倒数之间的区别就是:假设x是a的逆元,那么 a * x = 1(mod p),也就是只多了一个取余的操作,这个取余的操作,就会保证a的逆元不一定只是a的倒数。那么我们的逆元有什么作用呢?

并且取余还不满足下面式子:( a/b )%p = (a%p  /  b%p)  %  p ,那么我们如果遇到b过大必须在中间过程进行取余的操作,那么我们会发现在乘法中满足:(a*b) % p = (a%p  *  b%p) %p,那么我们只要将上面式子转换为下面乘法的式子就可以了

我们用inv(b)来表示b的逆元,那么他一定满足:b*inv(b) = 1(mod p)    ==>  b = 1/inv(b) ,那么我们代入上面的除法的式子:(a/b)%p =     (a * inv(b)) %p = (a%p  *  inv(b)%p) % p

这样我们就可以根据逆元来将除法取余的式子转换为乘法取余的式子

逆元的计算
我们这里先只介绍一种计算逆元的方式,利用费马小定理计算逆元,费马小定理:如果p是质数(素数),并且gcd(a,p) == 1, 那么就会满足下面的式子 ,当然了,既然p已经是素数,那么如果a < p那么就一定会满足这个式子,既然这样我们要得到 a^-1 我们就可以利用上面的式子来计算inv(a) : a^(p-2) = inv(a) (mod p)

这样我们就得到了我们需要的逆元:

实现:

ll quick_pow(ll a,ll b)
{
ll ans = 1;
while(b)
{
if(b & 1) ans *= a;
a *= a;
b >>= 1;
}
return ans;
}
quick_pow(a,p-2);
————————————————
版权声明:本文为CSDN博主「阿_波_」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/li1615882553/article/details/80001473

posted on 2020-03-22 21:00  Allen_lml  阅读(166)  评论(0编辑  收藏  举报