逆元浅析
来源:互联网 发布: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之类的大质数。
当然了,还可以通过扩展欧几里得之类的奇怪算法实现逆元。
不过作者比较蒟蒻,只会费马小定理。
有兴趣的同学可以去了解一下实现逆元的其他方法。
最后,感谢大家的支持。
欢迎各路大佬指正本文的问题。
如果你认为本文写得好,欢迎点赞与转发(转发请标明出处与原文链接)。
- 逆元浅析
- 元组Tuple浅析
- 享元模式浅析
- 浅析逆元&逆元的蛋用(完全版)
- Qt元对象机制浅析
- 浅析ETL过程中的元数据
- C ++友元的浅析(一)
- java元注解及源码浅析
- 逆元
- 逆元
- 逆元
- 逆元
- 逆元
- 逆元
- 逆元
- 逆元
- 【 逆元 】
- 【逆元】
- Maven项目启动报错:The absolute uri: http://java.sun.com/jsp/jstl/core cannot be resolved in either web.xml
- 处理大并发之一 对异步非阻塞的理解
- Python 中画图工具的使用
- NOIP 2000普及组 乘积最大 详解
- 并查集入门--hd 1213
- 逆元浅析
- hdu
- python 功能
- 实现密码需要同时包含数字和字母的需求
- 数字在排序数组中出现的次数
- 阻塞非阻塞与同步异步的区别
- C语言--Linux多线程pthread
- java SE基础知识点总结(01):编程环境的搭建
- 关于查询缓存的一个思考