Miller-Rabin

事先声明,因为菜鸡Hastin知识水平有限就是菜,因此语言可能不是特别规范,仅供理解.

step 0

问一个数\(p\)是否为质数,\(p<=10^{18}\).

一个简单暴力的办法是\(O( \sqrt{n})\)枚举约数.

然而显然会炸.

于是我们就有了Miller-Rabin.

讲了好多废话...

step 1

首先了解一下费马小定理:

若\(p\)为质数,则对于\(a\in[1,p-1]\)有\(a^{p}\equiv a(Mod\) \(p)\)

那么就有\(a^{p-1} \equiv 1( Mod\) \(p)\)

下面我们用数学归纳法来证明一下费马小定理:

显然\(a=1\)时结论成立,

若\(a=n\)时结论成立,

当\(a=n+1\)时,有

\((n+1)^p\)\(=\sum_{i=0}^{p}C_{p}^{i}n^{p-i}\)(二项式定理)

那么除了\(n^{p}\)和\(1\)这两项外,

其它的都有一个系数\(C_{p}^{i},i\in[1,p-1]\),所以都能被\(p\)整除.

而\(n^p\equiv n(Mod\) \(p)\),

所以\((n+1)^{p}\equiv n+1(Mod\) \(p)\),结论成立.

所以回到正题,如果对于一个数\(p\),存在\(a \in [1,p-1]\),\(a^{p-1}\not\equiv1(Mod\) \(p)\),则\(p\)一定不是质数.

然而仍然有一些数能够逃掉这种检测,

于是就有了

step 2

二次探测!

对于一个质数\(p\),若\(a \in[1,p-1]\),且\(a^2\equiv1(Mod\) \(p)\),则\(a=1\)或\(a=p-1\).

证明:

若\(a^2\equiv1(Mod\) \(p)\),则\(a^2-1\equiv 0(Mod\) \(p)\)

即\(p|(a+1)(a-1)\).

因为\(p\)为质数,且\(a\in [1,p-1]\),所以只有当\(a=1\)或\(a=p-1\)时上式才成立.

所以反过来想当\(a\)等于其它数时,\(p\)就不是质数了.

step 3

下面再来讲一下具体的实现.

首先大的思路是费马小定理,在中间用二次探测判定.

对于要判定的数\(p\),

设\(u=p-1\),则根据费马小定理有\(a^u\equiv 1(Mod\) \(p)\),\(a\in [1,p-1]\).

然后把\(u\)写成\(d*2^n\)的形式,也就是\((((d^2)^2)^2)^{2...}\)(n个2)

那么从\(d^2\)开始用二次探测判定,

最后再用费马小定理判定就行了.

而时间复杂度是\(O(log_{ \tiny 2}\) \(p)\).

并且一次的失误率是\(\frac{1}{4}\),

那么\(T\)次测试的失误率就是\(4^{-T}\),时间复杂度为\(O(Tlog_{\tiny 2}p)\),能够接受.

并且如果\(n<2^{64}\),只用选取\(a=2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37\)测试即可.

code:(似乎要开int128)

#include <iostream>
#include <cstdio>
#include <cstring>
#define int __int128
#define fre(x) freopen(x".in","r",stdin),freopen(x".out","w",stdout)
using namespace std; inline int read(){
int sum=0,f=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return f*sum;
} int p[101]={2,3,5,7,11,13,17,19,23,29,31,37};
int T,n,tot=12; inline int fpow(int a,int b,int p){
int ret=1;
for(;b;a=a*a%p,b>>=1) if(b&1) ret=ret*a%p;
return ret;
} inline bool Miller_Rabin(int n){
if(n<=2){
if(n==2) return 1;
return 0;
}
int u=n-1;
while(!(u%2)) u>>=1;
int d=u;
for(int i=0;i<tot&&p[i]<n;i++){
int x=p[i];u=d;x=fpow(x,u,n);
while(u<n){
int y=fpow(x,2,n);
if(y==1&&x!=1&&x!=n-1) return 0;
x=y;u<<=1;
}
if(x!=1) return 0;
}
return 1;
} signed main(){
T=read();
while(T--){
n=read();
if(Miller_Rabin(n)) puts("Yes");
else puts("No");
}
return 0;
}

[学习笔记] Miller-Rabin 质数测试的更多相关文章

  1. POJ1811_Prime Test【Miller Rabin素数测试】【Pollar Rho整数分解】

    Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29193 Accepted: 7392 Case Time ...

  2. HDU 3864 D_num Miller Rabin 质数推断+Pollard Rho大整数分解

    链接:http://acm.hdu.edu.cn/showproblem.php? pid=3864 题意:给出一个数N(1<=N<10^18).假设N仅仅有四个约数.就输出除1外的三个约 ...

  3. HDU1164_Eddy&#39;s research I【Miller Rabin素数测试】【Pollar Rho整数分解】

    Eddy's research I Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others ...

  4. STM32学习笔记(十) CAN通讯测试(环回模式)

    1.CAN通讯的理解 想学习CAN通讯,那么要对通讯协议有一定的认知.通讯协议是指通信双方对数据传送控制的一种约定.约定中包括对数据格式,同步方式,传输速度,传送步骤,检纠错方式以及控制字符定义等问题 ...

  5. AMQ学习笔记 - 17. 事务的测试

    概述 对事务机制进行测试. 测试实例 测试实例 结果预测 发送正常 3条消息入队 发送异常 0条消息入队 接收正常 3条消息出队 接收异常 0条消息出队 demo设计 设计图 测试分工 测试类 测试方 ...

  6. AMQ学习笔记 - 18. 持久化的测试

    概述 对持久化的有效性进行测试. 测试实例 测试实例 结果预测 持久化递送 重启ActiveMQ后,消息还在队列中 非持久化递送 重启ActiveMQ后,消息不在队列中 demo设计 jms-prod ...

  7. IGS_学习笔记08_IREP通过soapUI测试客户化Web Service调用(案例)

    20150819 Created By BaoXinjian

  8. IGS_学习笔记07_IREP通过页面测试客户化Web Service调用(案例)

    20150819 Created By BaoXinjian

  9. Spring学习笔记6——注解方式测试

    需要下载junit-4.12.jar和hamcrest-all-1.3.jar,将下载好的包导入到项目当中. 修改TestSpring, 并运行1. @RunWith(SpringJUnit4Clas ...

  10. spring框架学习笔记1:搭建测试

    Spring框架介绍: Spring框架涵盖了web.service.dao三层,本身是一个存放对象的容器 形象来说:Spring是项目中对象管家 Spring框架的两大核心思想:控制反转(IOC). ...

随机推荐

  1. 【Python爬虫案例学习】下载某图片网站的所有图集

    前言 其实很简短就是利用爬虫的第三方库Requests与BeautifulSoup. 其实就几行代码,但希望没有开发基础的人也能一下子看明白,所以大神请绕行. 基本环境配置 python 版本:2.7 ...

  2. C/C++語言 - 日常算法 - 蛇形填數

    C/C++語言 - 日常算法 - 蛇形填數 日期 : 2019-06-11 問題描述: 在n×n方阵里填入1,2,…,n×n,要求填成蛇形. 例如,n=4时方阵为: 10   11  12  1 9 ...

  3. Golang 传递任意类型的切片

    肯定有这样的一种场景,写一个函数,该函数可以接收任意类型的切片,完成相应的功能. 就好比这种情况 intSlice := []int{1,2,3,4,5,6,7,8} strSlice := []st ...

  4. Go基础编程实践(六)—— 文件

    检查文件是否存在 在此程序同目录下创建log.txt文件,以检测. package main import ( "os" "fmt" ) func main() ...

  5. FMX 隐藏任务栏 xe10

    找了好多信息,测试好些,xe10  隐藏只要以下命令 隐藏 ShowWindow(ApplicationHWND, SW_HIDE); 显示 ShowWindow(ApplicationHWND, S ...

  6. 解决使用RabbitTemplate操作RabbitMQ,发生The channelMax limit is reached. Try later.问题

    使用RabbitTemplate操纵RabbitMQ,每个RabbitTemplate等于一个connection,每个connection最多支持2048个channel,当hannel达到2048 ...

  7. Openshift概念

    Openshift是一个开源容器云平台,是一个基于主流的容器技术Docker和K8s构建的云平台.Openshift底层以Docker作为容器引擎驱动,以K8s作为容器编排引擎组件,并提供了开发语言, ...

  8. Python进阶(八)----模块,import , from import 和 `__name__`的使用

    Python进阶(八)----模块,import , from import 和 __name__的使用 一丶模块的初识 #### 什么是模块: # 模块就是一个py文件(这个模块存放很多相似的功能, ...

  9. 30个关于Shell脚本的经典案例(中)

    本文目录 11.iptables自动屏蔽访问网站频繁的IP 12.判断用户输入的是否为IP地址 13.判断用户输入的是否为数字 14.给定目录找出包含关键字的文件 15.监控目录,将新创建的文件名追加 ...

  10. tomcat 安装记录 centos7 开放对外端口

    //端口查询 [root@CentOS7 bin]# firewall-cmd --query-port=9090/tcp no //添加端口 [root@CentOS7 bin]# firewall ...