[note] 素数判定与分解质因数

news/2025/11/14 20:37:21/文章来源:https://www.cnblogs.com/Lijiangjun4/p/19218954

在某些毒瘤的数论题中,可能出现对 \(10^{18}\) 的范围内的数质因数分解的情况。这时,可以使用 FermatMiller-Rabin 算法进行素性判定Pollard-Rho 算法寻找非平凡因子,两者结合以快速质因数分解。

Fermat 素性检验

Fermat 素性检验是最基本的概率性素性检验。该方法依靠费马小定理进行:

费马小定理
\(p\) 是素数,则对于任意的 \(a\) 满足 \(p\nmid a\),都有 \(a^{p-1}\equiv 1 \pmod p\)

证明

首先证明对于 \(i=1,2,\dots,a-1\),都有 \(ia\bmod p\) 互不相等。考虑反证,假设 \(ia\bmod p=ja\bmod p\),那么 \(ia\equiv ja\pmod{p}\iff(i-j)a\equiv 0\pmod{p}\),然而 \((i-j)\)\(a\) 均不是 \(p\) 的倍数,所以矛盾。

那么 \(ia\bmod p\) 是一个 \(1\sim p-1\) 的排列,则

\[\prod_{i=1}^{p-1}i=\prod_{i=1}^{p-1}ia\bmod p\equiv\prod_{i=1}^{p-1}ia=a^{p-1}\prod_{i=1}^{p-1}i\pmod{p} \]

这说明

\[(a^{p-1}-1)\prod_{i=1}^{p-1}i\equiv0\pmod{p} \]

由于 \(\prod_{i=1}^{p-1}i\) 不是 \(p\) 的倍数,则 \(a^{p-1}-1\)\(p\) 的倍数,也就是 \(a^{p-1}\equiv1\pmod{p}\)

因此,我们猜想费马小定理的逆命题:如果对于任意的 \(a\) 满足 \(p\nmid a\)\(a^{p-1}\equiv1\pmod p\),那么 \(p\) 为质数。我们在 \([2,p-1]\) 内随机几个 \(a\),这样 \(p\nmid a\) 一定成立,如果存在 \(a\) 不满足 \(a^{p-1}\equiv1\pmod{p}\)\(p\) 就是合数,否则就是质数。

然而费马小定理的逆命题是不成立的。事实上,对于某些合数,就算 \([2,p-1]\) 内的所有数都检验一遍都满足 \(a^{p-1}\equiv1\pmod{p}\),比如 Carmichael 数,遇到这种数就原地歇菜了。因此,Fermat 素性检验是不够强的,下文将讲解更强的方法。

参考代码
long long qpow(long long a,long long b,long long mod)
{long long res=1;while(b){if(b&1) res=res*a%mod;a=a*a%mod;b>>=1;}return res;
}
bool Fermat(long long p)
{for(int i=1;i<=8;i++){int a=rand()%(n-2)+2;if(qpow(a,p-1)!=1) return false;}return true;
}

Miller-Rabin 素性检验

Miller-Rabin 是一种正确率更高的素性检验算法。首先引入一个定理:

二次探测定理
对于质数 \(p\)\(x^2\equiv1\pmod p\) 的解为 \(x\equiv1\pmod{p}\)\(x\equiv p-1\pmod{p}\)

证明

证明是简单的。\(x^2\equiv1\pmod{p}\iff x^2-1=(x+1)(x-1)\equiv0\pmod{p}\),则 \(x-1\equiv0\pmod{p}\)\(x+1\equiv0\pmod{p}\),得证。

根据这个,我们得到定理:

对于奇质数 \(p\),令 \(d\times2^r=p-1\)\(a\) 为奇数),则对于任意的 \(a\le p\),以下两个条件至少有一个成立:

  1. \(a^d\equiv1\pmod{p}\)
  2. 存在 \(0\le i<r\),满足 \(a^{d\times 2^i}\equiv p-1\pmod{p}\)
证明

\(s_i=a^{d\times2^{i}}\),由费马小定理,\(s_r=a^{d\times2^r}=a^{p-1}\equiv1\pmod{p}\)。设 \(s_i\) 为最小的满足 \(s_i\equiv1\pmod p\)\(i\),则分类讨论:

  1. \(i=0\):则 \(s_i=a^d\equiv1\pmod{p}\)
  2. \(i>0\):则 \(s_i=s_{i-1}^2\equiv1\pmod{p}\),由于 \(i\) 是最小的,则由二次探测定理得 \(s_{i-1}\equiv p-1\pmod{p}\)

猜想这个定理的反命题:随机几个 \(a\),判断一下符不符合这个定理,不符合就是合数,否则是质数。

遗憾的是,随机 \(a\) 能正确通过 Miller-Rabin 的概率至多为 \(\frac{1}{4}\)。不过在 OI 中,使用 \(\{2,325,9375,28178,450775,9780504,1795265022\}\)\(\{2,3,5,7,11,13,17,19,23,29,31,37\}\) 中的数作为 \(a\) 进行检测,能保证 long long 范围内的数 100% 正确判断。

实现细节上,注意 long long 和 __int128 的使用。

参考代码
long long pr[7]={2,325,9375,28178,450775,9780504,1795265022};
long long qpow(long long a,long long b,long long p)
{int128 res=1;while(b){if(b&1) res=res*a%p;a=(int128)a*a%p;b>>=1;}return res;
}
bool Miller_Rabin(long long x,long long p)
{if(x<3||x%2==0) return x==2;long long d=x-1,c=0;while(d%2==0) d>>=1,c++;int128 t=qpow(p,d,x);if(t==1) return true;for(int i=0;i<c;i++){if(t==x-1) return true;t=t*t%x;}return false;
}
bool isprime(long long x)
{if(x<V) return !p[x];if(x<=1) return false;for(int i=0;i<7;i++){if(x==pr[i]) return true;if(x%pr[i]==0) return false;if(!Miller_Rabin(x,pr[i])) return false;}return true;
}

Pollard-Rho 算法

Pollard-Rho 算法是一种随机化算法,能在期望 \(O(\sqrt{p})\) 的时间复杂度内找到 \(n\) 的一个非平凡因子(即除了 \(1\)\(n\) 以外的因子),其中 \(p\)\(n\) 的最小质因数。

首先有一个生日悖论:

生日悖论
随机生成一个值域在 \([1,n]\) 的序列,第一个重复出现的数字前面期望有 \(\sqrt\frac{\pi n}{2}\) 个数。

因此,我们随机生成一个序列 \(x\),期望在生成到 \(\sqrt{p}\) 个数的时候就出现 \(x_i\equiv x_j\pmod{p}\),此时 \(\gcd(|x_i-x_j|,n)\) 即为所求。但由于 \(p\) 是不确定的,我们只能用 \(\gcd(|x_i-x_j|,n)>1\) 这个条件判断每一对 \((x_i,x_j)\),复杂度退化到 \(O(\sqrt{n})\) 的了。我们应重新设计 \(x\) 的生成方式,使得不用对每一组 \((x_i,x_j)\) 进行判断。

设计函数 \(f(x)=(x^2+c)\bmod n\)\(c\) 为随机的常数),令伪随机序列 \(x\) 满足 \(x_0=0\)\(x_i=f(x_{i-1})\),将推导过程画图,会长这样:

注意到 \(f\) 函数的取值为 \([0,n-1]\) 之间,因此必然会形成如图所示的 \(\rho\) 形。

为什么要这样设计呢?因为 \(f\) 函数有神秘性质:若 \(i\equiv j\pmod{p}\),则 \(f(i)\equiv f(j)\pmod{p}\),对 \(i\)\(j\)\(f\) 映射相当于两个点都在图中走了一步,两个点距离不变。因此,对于 \(i-j\) 相等的所有 \((x_i,x_j)\) 只需检验一遍就够。

实现上,维护两个指针,一快一慢,快的一次跳 \(2\) 步,慢的一次跳 \(1\) 步,这样就能检查所有距离的 \((x_i,x_j)\),进入环后快的追慢的还会相遇。复杂度 \(O(n^{\frac{1}{4}}\log n)\)

注意 \(\gcd(|x_i-x_j|,n)\) 可能为 \(n\),或者啥都没得到,此时应该重选 \(c\) 再做一遍。一定记得先对 \(n\) 做素性检验,防止质数把算法搞炸。

参考代码
//代码来源:知乎 Pecco,侵删
long long Pollard_Rho(long long N)
{if (N == 4)return 2;if (is_prime(N))return N;while (1){long long c = rand()%(n-1)+1; auto f = [=](long long x) { return ((__int128)x * x + c) % N; };long long t = f(0), r = f(f(0));while (t != r){long long d = gcd(abs(t - r), N);if (d > 1)return d;t = f(t), r = f(f(r));}}
}

参考文章

https://www.cnblogs.com/biyimouse/p/18924291

https://zhuanlan.zhihu.com/p/267884783

https://oi-wiki.org/math/number-theory/pollard-rho/

https://oi-wiki.org/math/number-theory/prime/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/965699.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

不能识别adb/usb口记录 - 实践

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

恭喜自己,挑战成功! - Ghost

恭喜自己,挑战成功! 我终于,拿省一啦! 正文: 在2025年8月18日,本人开始了一项挑战 挑战三个月达省一 在三个月后,2025年11月14日,NOI官网发布了分数and分数线 本人以高出一等分数线10分的分数(250pts),成功…

如何在测试覆盖不足后补充验证

测试覆盖不足是项目质量的重大隐患,一旦发现(尤其是当它已导致线上问题时),团队必须立即采取系统性的补充验证措施。核心策略是停止盲目开发,转而执行一套以风险为导向的补救流程。 首先,必须立即对未覆盖的区域…

react动态表单

来个例子 比如有两种登录方式 // 导入表单验证库 import * as z from zod; // 导入消息提示组件 import { toast } from sonner; import { useState } from react; // 导入 UI 组件 import { Input } from @repo/shadc…

完整教程:PDFBox - PDDocument 与 byte 数组、PDF 加密

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

Dark Side of the Moon

“Speak to Me” "Ive been mad for fucking years, absolutely years, been over the edge for years, been working me buns off for bands..." "Ive always been mad, I know Ive been mad, like mo…

flask:自定义异常

一,代码: 自定义异常:class ApiError(Exception):""""API接口异常错误"""messsage = ""# 默认错误码status_code = 400# 自定义一个return_code, 作为更细粒的错误代码…

图片合集

\(sin(2\theta)=2sin(\theta)cos(\theta)=\frac{2tan(\theta)}{1+tan^2(\theta)}\) \(cos(2\theta)=cos^2(\theta)-sin^2(\theta)=\frac{1-tan^2(\theta)}{1+tan^2(\theta)}\) \(tan(2\theta)=\frac{2tan(\theta)}{1-t…

升幂引理(LTE)

记 \(\nu_p(n)\) 表示 \(n\) 的标准分解中素数 \(p\) 的幂次,即 \(p^{\nu_p(n)} \parallel n\)。 该引理分为两部分:设 \(a, \, b\) 为不等正整数且 \(p \mid a - b\),\((p, \, ab) = 1\),若 \(p\) 为奇素数,则 \(…

OpenWrt路由的端口映射问题

之前做过AI大模型搭建,想将搭建的访问能开放到外部局域网,方便其他人访问,需要一些网络设置,就在这个网络配置上踩了些坑。 想在最外局域网中访问,但是自己这边用了两级的路由,第一级是小米的无线路由,以及上一…

解码IPC-管道与信号

进程间通信(IPC) 进程间通信(Inter Process Communication,简称 IPC)是进程间的信息交换,核心目的包括数据传输、共享资源、控制进程,方便对进程的管理与调度。常见 IPC 方式有管道通信、信号通信、共享内存、消…

算法沉淀第七天(AtCoder Beginner Contest 428 和 小训练赛) - 详解

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

How-to-extract-text-from-PDF-Image-files-OCR-CarlZeng

本文阐述如何自建并使用OCR识别图片或PDF中文字(转化成文本等进一步处理), 以及NetSuite调用OCR API的场景雏形. How to extract text from PDF(Image) files. 20251113 引入自建ocr服务docker部署OCR项目 支持离线+…

Web应用模糊测试完全指南

本文详细介绍了使用ffuf工具进行Web应用模糊测试的完整流程,包括目录发现、子域名枚举、暴力破解攻击、参数挖掘等多种技术,提供了实用的命令示例和配置参数说明。Fuzzing Web Apps Full Guide 前言 在这篇博客中,我…

升鲜宝供应链管理系统、各端的访问地址及nginx 真实的配置方法

server {listen 443 ssl;server_name sxbscm.sxbscm.com;# 1. SSL 证书配置(关键:补充中间证书,避免链不完整导致兼容问题)ssl_certificate /mnt/sxbscm/ssl/sxbscm.sxbscm.com/sxbscm.sxbscm.com.pem; # 主证书(…

2025.11.14模拟赛

IOI赛制,fjj的模拟赛,题目质量非常高(准确来说是非常适合我们),fjj强大的%%% 赛时看T1,然后打了60暴力,已经知道用组合数来求了,然后也知道固定左上角的来求答案,但是就是没想明白怎么去除重复的贡献 然后一看…

【HT-086-Div.2】错乱的集合

【HT-086-Div.2】错乱的集合 题解比赛现场 更阅读体验的阅读体验 是个好题。但是我赛时怎么什么都不会。首先简化一下题面:\(s\) 和 \(t\) 被认为是相同的,当且仅当 \(s=t\) 或 \(|t|=|s|-1\) 且 \(t\) 是 \(s\) 的后…

uiautomator2元素查看器WEditor的安装和启动

WEditor 一、WEditor简介 在执行APP UI自动化测试时,需要使用到元素定位,通常我们会直接使用appium Desktop的Inspector。介绍另一款UI元素定位的工具--WEditor。WEditor能够提供辅助编写脚本,定位元素,调试代码等…

深入解析:【从0开始学习Java | 第22篇】反射

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …