当前位置: 首页 > news >正文

Miller Rabin学习笔记

这真是个优美的东西qwq

O ( n ) O(\sqrt{n}) O(n ) 判素数非常好写,但这样的复杂度不够优秀,而学会了Miller Rabin算法就可以用神奇的方法做到 O ( n 1 / 4 ) O(n^{1/4}) O(n1/4) 判断了qwq。

前置芝士

  • 费马小定理:当 p p p 为素数切 gcd ⁡ ( a , p ) = 1 \gcd(a,p)=1 gcd(a,p)=1,有 a p − 1 ≡ 1 a^{p-1}\equiv1 ap11 ( m o d    p ) (\mod p) (modp),这是 p p p 为素数的必要不充分条件。
  • 二次探测定理:当 p p p 为素数且 x ∈ ( 0 , p ) x\in(0,p) x(0,p) x 2 ≡ 1 x^2\equiv1 x21 ( m o d    p ) (\mod p) (modp),则 x = 1 x=1 x=1 x = p − 1 x=p-1 x=p1。将1移到等式左边即可证明。

Miller Rabin

首先我们知道,除了 2 2 2 以外的素数都是奇数,那么特判掉 2 2 2,其余素数 − 1 -1 1 都是偶数。

假设当前要判定的奇数 p p p 为素数,那么由费马小定理可知,对于任意 a ∈ ( 0 , n ) a\in(0,n) a(0,n) a p − 1 ≡ 1 a^{p-1}\equiv1 ap11 ( m o d    p ) (\mod p) (modp),而 p − 1 p-1 p1 又可以分解成 2 k × t ( t m o d    2 = 1 ) 2^k\times t(t\mod2=1) 2k×t(tmod2=1) 的形式,当 k ≠ 0 k\neq0 k=0 时,根据二次探测定理,可以一步一步降幂: a 2 k × t ≡ 1 ( m o d    p ) ⇒ a 2 k − 1 × t ≡ 1 ( m o d    p ) a^{2^k\times t}\equiv1(\mod p)\Rightarrow a^{2^{k-1}\times t}\equiv1(\mod p) a2k×t1(modp)a2k1×t1(modp) a 2 k − 1 × t ≡ n − 1 ( m o d    p ) a^{2^{k-1}\times t}\equiv n-1(\mod p) a2k1×tn1(modp),当第一种情况时又可以重复上述过程,直到 a 2 x × t ≡ n − 1 ( m o d    p ) a^{2^x\times t}\equiv n-1(\mod p) a2x×tn1(modp) a t ≡ 1 ( m o d    p ) a^t\equiv 1(\mod p) at1(modp)

于是Miller Rabin算法每次选取一个素数 a a a 来对 p p p 进行检验,若存在 x x x 使得 a 2 x × t ≡ n − 1 ( m o d    p ) a^{2^x\times t}\equiv n-1(\mod p) a2x×tn1(modp) a t ≡ 1 ( m o d    p ) a^t\equiv 1(\mod p) at1(modp),则称 p p p 通过了当前素性测试。

我不会证明但一次素性测试错误率约为 1 4 \frac{1}{4} 41,这里的错误是指素数一定能通过测试,合数不一定不能通过测试。所以在竞赛中常用 30 30 30 以内的所有质数进行测试,这样得出的结果错误的概率极低,可以认为是正确的。

Code

由于 p p p 大约在 1 0 18 10^{18} 1018 级别才会用到Miller Rabin,所以乘法的时候会有爆long long问题,要用龟速乘。

const int qwq[]={0,2,3,5,7,11,13,17,19,23,29};
inline int mul(int x,int y,int mod){
	int res=0;
	for(;y;y>>=1){
		if(y&1) res=(res+x)%mod;
		x=(x<<1)%mod;
	}
	return res;
}
inline int ksm(int x,int y,int mod){
	int res=1;
	for(;y;y>>=1){
		if(y&1) res=mul(res,x,mod);
		x=mul(x,x,mod);
	}
	return res;
}
inline bool MR(){
	if(n==2) return 1;
	if(n<2||!(n&1)) return 0;//特判 
	int t=n-1,k=0;
	while(!(t&1)) ++k,t>>=1;
	ff(i,1,10){
		if(qwq[i]==n) return 1;
		int a=ksm(qwq[i],t,n),now=a;
		ff(j,0,k){
			if(j) now=mul(a,a,n);
			if(now==1&&a!=1&&a!=n-1) return 0;//不满足二次探测定理 
			a=now;
		}
		if(a!=1) return 0;//不满足费马小定理 
	}
	return 1;
}

相关文章:

  • 3D角色PBR入门简述
  • java毕业设计开题报告javaweb敬老院管理系统的设计和实现|养老院
  • 为什么电脑一用wps就卡住了?
  • Dubbo - 远程debug
  • Vue3+Vite+TS:多入口项目搭建(简单版)
  • 通用操作系统服务(一)、argparse模块
  • 安装MinGW win安装gcc
  • 从任正非的内部信,看系统开发公司如何度过寒冬
  • 面向智慧文博的知识图谱构建综述
  • 技术分享 | Bug定位方法
  • Web3的流支付代表Zebec,熊市布局的价值逻辑
  • ZFS文件系统预研资料
  • 不同时代下的中秋之美--python学习应用心得
  • Dropout和BN为什么不能共同使用?
  • Java 线程池原理及最佳实践(1.5W字,面试必问)
  • 10个确保微服务与容器安全的最佳实践
  • 11111111
  • Spring Cloud Feign的两种使用姿势
  • Spring技术内幕笔记(2):Spring MVC 与 Web
  • swift基础之_对象 实例方法 对象方法。
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 一起来学SpringBoot | 第十篇:使用Spring Cache集成Redis
  • ​​​​​​​GitLab 之 GitLab-Runner 安装,配置与问题汇总
  • ​创新驱动,边缘计算领袖:亚马逊云科技海外服务器服务再进化
  • ​什么是bug?bug的源头在哪里?
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • (13):Silverlight 2 数据与通信之WebRequest
  • (SpringBoot)第七章:SpringBoot日志文件
  • (二)fiber的基本认识
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (附源码)springboot助农电商系统 毕业设计 081919
  • (附源码)计算机毕业设计SSM智能化管理的仓库管理
  • (六)软件测试分工
  • (十一)c52学习之旅-动态数码管
  • (算法)前K大的和
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • .mkp勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
  • .net core使用RPC方式进行高效的HTTP服务访问
  • .Net 垃圾回收机制原理(二)
  • .Net程序猿乐Android发展---(10)框架布局FrameLayout
  • .NET大文件上传知识整理
  • .Net转Java自学之路—SpringMVC框架篇六(异常处理)
  • @ModelAttribute注解使用
  • [20161101]rman备份与数据文件变化7.txt
  • [AI]文心一言爆火的同时,ChatGPT带来了这么多的开源项目你了解吗
  • [AIGC] Spring Interceptor 拦截器详解
  • [AIGC] 如何建立和优化你的工作流?
  • [BZOJ4016][FJOI2014]最短路径树问题
  • [CISCN2019 华东南赛区]Web4
  • [flink总结]什么是flink背压 ,有什么危害? 如何解决flink背压?flink如何保证端到端一致性?
  • [HNOI2008]Cards
  • [i.MX]飞思卡尔IMX6处理器的GPIO-IOMUX_PAD说明
  • [I2C]I2C通信协议详解(一) --- 什么是I2C
  • [Java][算法 双指针]Day 02---LeetCode 热题 100---04~07
  • [JavaWeb]—前端篇