逆元浅析

来源:互联网 发布:java数组添加元素 编辑:程序博客网 时间:2024/06/06 07:33

前言:

在网上看到很多关于逆元的文章,大多都是一些看了就令人一脸懵逼的证明。

其实,我们只要清楚逆元的作用就可以了,证明什么的不是我们现阶段该学的。


应用:

在求排列组合的时候,我们经常会碰到这样一个问题:

计算(n!)/(m!)%p,其中,p>m,p是一个质数,%表示取模。


你可以先计算出n!,然后再计算出m!,最后相除取模p。

但如果n,m很大呢?难道要高精度?


你可能会说,我们为什么不能计算n!与m!时每次相乘都取模一个p,最后再相除呢?

显然不行,这样你最后得出的n!与m!都是在模p意义下的,再相除答案就会出错。


那我们就尝试把除法转化成乘法,这样就可以边乘边模p了。


怎么把除法转化成乘法呢?就要用到逆元了。


费马小定理:

我们先来引入一个叫作费马小定理的东西:

 a(p-1)≡1(mod p),其中p为质数,a与p互质。


这条等式我们现阶段不需要知道如何去证明,只需要记住就好了。


我们把等式两边同时除以a,则可得:

a(p-2)≡(1/a)(mod p)


那么,如果我们让当前一个乘积s除以a,在模p意义下就等于让s*a(p-2) 


我们在上面的例题中不用考虑a与p是否互质,因为a=[1..m],而m<p,p为一个质数,所以a与p一定互质。


那么,上面的例题的做法就显而易见了。


我们把(n!)/(m!)%p转化成(n!%p)*(1(p-2)*2(p-2)*3(p-2)*……*m(p-2)%p)


每次相乘都模p就好了。


注意,求x(p-2)要用快速幂。


总结:

所以说,狭义上,逆元就是通过某种运算把除法转化成与其等价的乘法。


上文中,我们是用费马小定理实现逆元的,

但费马小定理实现逆元有一个局限性:模数必须是质数,并与乘数互质。


其实这也没有什么关系,一般的题目的模数都是10^9+7之类的大质数。


当然了,还可以通过扩展欧几里得之类的奇怪算法实现逆元。

不过作者比较蒟蒻,只会费马小定理。

有兴趣的同学可以去了解一下实现逆元的其他方法。


最后,感谢大家的支持。

欢迎各路大佬指正本文的问题。


如果你认为本文写得好,欢迎点赞与转发(转发请标明出处与原文链接)。



原创粉丝点击