[算法]Miller-Robbin素数判定
一、实现原理
我们以前都是怎么判断素数的呢:
试除法: 若一个正整数N为合数,则存在一个能整除N的数k,其中\(2\leqslant k \leqslant \sqrt N\)。
具体实施如下:
inline int is_prime(int n){
if(n<2) return 0;
for(int i=2;i<=sqrt(n);i++){
if(n%i==0) return 0;
}
return 1;
}
这种方法的时间复杂度为\(O(\sqrt n)\)。
现在,我们希望更快地判断一个数是否为素数。
我们可以借助费马小定理来判断:
如果p是一个质数,而整数a不是p的倍数,则有
\]
Miller-Robbin素数判定就是基于上述定理实现的,如果我们随机枚举一个\(a\),且\(a\)满足费马小定理,那么\(p\)就是素数。所以Miller-Robbin素数判定是一种随机性算法。
需要注意的是,我们这样判断素数的方法实际上利用的是费马小定理的逆定理。不幸的是,费马小定理的逆定理并不是一个真命题。
- 存在\(a=2,p=341\)时满足费马小定理,而\(341=11*31\)却是合数
我们把像341这样的数称作伪素数。实际上,伪素数有无穷多组。
这意味着一次判断不足以保证我们的程序正确。当然,解决这个问题也十分简单。
我们只需要重复操作大约30次,便能将正确率提升到我们期待的水平。
另外,我们使用快速幂来计算\(a^{p-1}\)。总复杂度为\(O(logn)\)。
下面给出Miller-Robbin素数判定的模板:
int qpow(int a,int b,int mod){//快速幂
int res=1;
while(b){
if(b&1) res=(res%mod*a)%mod;
a=(a%mod)*a%mod;
b>>=1;
}
return res;
}
bool query_prime(int x){
if(x==2)return true;
if(x==1)return false;
for(int i=1;i<=30;i++){
int base=rand()%(x-1)+1;//随机枚举a
if(qpow(base,x-1,x)!=1) return false;//计算a^(p-1)%p的值
}
return true;
}
二、应用
判断一个正整数是否为素数
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int qpow(int a,int b,int mod){//快速幂
int res=1;
while(b){
if(b&1) res=(res%mod*a)%mod;
b>>=1;
a=(a%mod)*a%mod;
}
return res;
}
inline int miller_robbin(int num){//核心代码
for(int i=1;i<=30;i++){
int base=rand()%(num-1)+1;
if(qpow(base,num-1,num)!=1) return 0;
}
return 1;
}
signed main(){
int num;
scanf("%d",&num);
if(num==1){
printf("NO");
return 0;
}
miller_robbin(num)?printf("YES\n"):printf("NO\n");
return 0;
}
附赠一道水题:(主要是练习素数判定)
AT1476 素数判定
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll qpow(ll a,ll b,ll mod){
ll res=1;
while(b){
if(b&1)res=(res%mod*a)%mod;
a=(a%mod)*a%mod;
b>>=1;
}
return res;
}
bool query_prime(ll x)
{
if(x==2)return true;
if(x==1)return false;
for(int i=1;i<=30;i++){
ll base=rand()%(x-1)+1;
if(qpow(base,x-1,x)!=1)return false;
}
return true;
}
int main()
{
srand(time(NULL));
ll num;
scanf("%lld",&num);
if(query_prime(num)||(num%2!=0&&num%3!=0&&num%5!=0&&num!=1))printf("Prime\n");
else printf("Not Prime\n");
return 0;
}
三、小结
使用Miller-Robbin素数判定,我们可以将复杂度降低至\(O(logn)\)级别(常数阶可以被忽略)。这样比原来的方法会快很多。

[算法]Miller-Robbin素数判定的更多相关文章
- Miller-Rabin算法 codevs 1702 素数判定 2
转载自:http://www.dxmtb.com/blog/miller-rabbin/ 普通的素数测试我们有O(√ n)的试除算法.事实上,我们有O(slog³n)的算法. 定理一:假如p是质数,且 ...
- HDU2138 素数判定
HDU2138 给定N个32位大于等于2的正整数 输出其中素数的个数 用Miller Rabin 素数判定法 效率很高 数学证明比较复杂,略过, 会使用这个接口即可. #include<iost ...
- Miller Rabin素数检测与Pollard Rho算法
一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...
- 数学#素数判定Miller_Rabin+大数因数分解Pollard_rho算法 POJ 1811&2429
素数判定Miller_Rabin算法详解: http://blog.csdn.net/maxichu/article/details/45458569 大数因数分解Pollard_rho算法详解: h ...
- 10^9以上素数判定,Miller_Rabin算法
#include<iostream> #include<cstdio> #include<ctime> #include<string.h> #incl ...
- 公钥密码之RSA密码算法大素数判定:Miller-Rabin判定法!
公钥密码之RSA密码算法大素数判定:Miller-Rabin判定法! 先存档再说,以后实验报告还得打印上交. Miller-Rabin大素数判定对于学算法的人来讲不是什么难事,主要了解其原理. 先来灌 ...
- Miller_Rabin()算法素数判定 +ollard_rho 算法进行质因数分解
//****************************************************************// Miller_Rabin 算法进行素数测试//速度快,而且可以 ...
- FZU 1649 Prime number or not米勒拉宾大素数判定方法。
C - Prime number or not Time Limit:2000MS Memory Limit:32768KB 64bit IO Format:%I64d & % ...
- algorithm@ 大素数判定和大整数质因数分解
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<time.h> #in ...
随机推荐
- Dubbo 扩展点加载机制:从 Java SPI 到 Dubbo SPI
SPI 全称为 Service Provider Interface,是一种服务发现机制.当程序运行调用接口时,会根据配置文件或默认规则信息加载对应的实现类.所以在程序中并没有直接指定使用接口的哪个实 ...
- JavaScript----流程控制语句
##特殊语法 1.语句以;结尾,如果一行只有一条语句,则;可以省略(不建议)2.变量的定义使用var关键字,也可以不使用 * 用:定义的变量是局部变量 * 不用:定义的变量是全局变量(不建议使用) # ...
- 两个看似相同,结果不同的SQL逻辑
一朋友问我的,看着挺有意思,记录一下: 表item1,里面有上面三个字段,一共10条数据,接下来有两个相似的sql语句得到了不一样的查询结果. 表数据如下: 两条SQL及查询结果: 我的理解答: S ...
- Springboot学习笔记【持续更新】
1.Springboot四大核心: 自动配置 与Spring应用程序和常见的应用功能,Springboot能自动提供相关配置 起步依赖 告诉Springboot需要什么功能,它就能引入需要的依赖库 A ...
- 初学jQuery使用方法
jQuery引用 <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></scri ...
- Win10远程桌面发生身份验证错误,要求的函数不受支持
昨儿个使用远程桌面,意外发的发现连不上测试环境了.身边的同事也有连不上的.一开始以为是远程机器可能出了问题,但是而后排查确认是自个儿机器问题.原因在与机器前天晚上自动升级了系统补丁,也有部分网友反映了 ...
- 从火车站车次公示栏来学Java读写锁
Java多线程并发之读写锁 本文主要内容:读写锁的理论:通过生活中例子来理解读写锁:读写锁的代码演示:读写锁总结.通过理论(总结)-例子-代码-然后再次总结,这四个步骤来让大家对读写锁的深刻理解. 本 ...
- vulnhub~sunset:dusk1
晚上闲来无事,准备做个target,结果是各种错误.在睡觉前还是没有顺利的做出来.先将TroubleSHOOTing 总结如下: 在用hydra爆破mysql的时候,发现 'MySql Host is ...
- HDU 2147kiki's game(巴什博弈变形)
题目链接 思路如下 P : 必胜点,那个人先走到 含P的点,那个这个人一定会输, N:必败点,谁走到这个点谁输! 在这一个题中: 某个点是P还是 N,之与 ⬅️左边第一个点.⬇️下边第一个点.↙️左下 ...
- linux硬件资源问题排查:cpu负载、内存使用情况、磁盘空间、磁盘IO
在使用过程中之前正常的功能,突然无法使用,性能变慢,通常都是资源消耗问题,资源消耗可以从以下几个方面去排查.对于已经安装硬件资源监控软件(zabbix)的环境,直接使用硬件资源监控软件(zabbix) ...