【luogu P4718】【模板】Pollard-Rho算法(数学)(也含 Miller Rabin)
【模板】Pollard-Rho算法
题目链接:luogu P4718
题目大意
要你求一个数的最大质因子。
思路
Miller Rabin
首先,这种题肯定要判断一个数是不是素数。
但普通的方法会爆炸。
于是我们要用 Miller Rabin。
这是一个 判断质数的东西,运用了费马小定律和二次探测定理。
费马小定理
(条件是 是质数)
那我们可以根据这个来判断,随机几次 ,看是否成立,如果不成立就说明不行。
但也会有一些数,它是合数,但你就是找不到 使得式子不满足,这些数叫做 Carmichael 数,就比如 。
这些数会使得判定出现误差,那我们考虑怎么搞。
二次探测定理
若 , 为质数,则 一定可以被 和 其中一个整除。
证明其实很简单:
然后就很显然了, 是质数,所以就一定有倍数关系了。
然后再想想就发现 。
然后如果 那又可以继续二次探测!
那转回到费马小定理:
(前提是 是偶数)
然后就搞,然后就按这个来二次探测就可以了。
这么搞了之后,就很难会出错,大概 才会有一个出错,所以可以忽略不计。
然后不难看到要用点快速幂快速乘。
Pollard-Rho 算法
但你只能判断质数还不行,你还要分解质因数啊。
这时候就要用 Pollard-Rho 算法了,可以快速的将一个你确实是合数的数找到它的其中一个因子。
GCD
我们先从 GCD 来看,因为是合数,所以必然会有小于 的因子。那我们考虑随机一个数,看它与 的 是否大于 ,得到的 就是一个因子。那这样选到的可能就是 。
但在 面前,还是太弱小了,没有我们要的速度。
x^2+c
这是一个玄学的随机方法,可以使得你找到跟 有非 公约数的概率会增加。
这个方法是利用了生日悖论,它不符合生活经验,但是可以推导出来没问题的东西。
它的 一开始是随机的,然后让 ,然后每次拿 去跟 求 。
它能搞到的概率十分之高,只能用玄学来形容。
判环
它这种方法很优秀,但是你因为生成过程中会取模,搞了多次一定会有环,那你如果这样都没找到,那你一直找下去都不会有结果,还不如重新随机 ,重新开搞。
那你就要判环。
我们可以用倍增的思想, 记住 位置, 跑当前数量的一倍的次数,然后再记住,再跑。
因为有倍增,那 位置相同时, 一定跑到了圈,而且不会多跑太多。
二次优化
然后你发现你每次判断都要求 ,这会让复杂度由 变成 。
虽然 很小,但毕竟是 ,会让整个变慢一些。
你发现取模的数不是质数。然后有这么一个质数:
如果模数和被模的数都有一个公约数,那取模结果也是这个公约数的倍数。
那我们可以把中途的 都乘起来,那只要其中有一个跟 有非 共约数,你乘起来的数跟 就有非 公约数。
那我们可以多算几次 ,再求一次 ,经过计算和测试,一般连续算 次再 一次是最优的,跑的很快。
但你会发现会有一点小问题。
我们可能跑了没有 次,就出现了环。然后就导致还没有求出答案,就退了出来。
或者由于算法过度优秀(bushi,乘积乘着乘着直接变 倍数,取模直接是 ,那没有必要干等着。
那处理第一个问题,我们可以用倍增来解决,在每个 要重新换位置的时候我们也做一次 ,因为是倍增的时候才 所以影响不大。
那第二个简单的也做一个判断就可以了。
然后就好啦。
代码
__EOF__

本文链接:https://www.cnblogs.com/Sakura-TJH/p/luogu_P4718.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现