[算法]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 ...
随机推荐
- 基于 HTML5 WebGL 与 GIS 的智慧机场大数据可视化分析【转载】
前言:大数据,人工智能,工业物联网,5G 已经或者正在潜移默化地改变着我们的生活.在信息技术快速发展的时代,谁能抓住数据的核心,利用有效的方法对数据做数据挖掘和数据分析,从数据中发现趋势,谁就能做到精 ...
- angualrjs 总结 随记(三)
$sanitize和$sce服务的使用方法 $sanitize会把标签的属性都移除,以及绑定在元素上的事件.仅保留了标签和内容 $q服务的使用1. 创建一个Service,去服务器读取数据: 2. 在 ...
- 一文洞悉JVM内存管理机制
前言 本文已经收录到我的Github个人博客,欢迎大佬们光临寒舍: 我的GIthub博客 学习导图: 一.为什么要学习内存管理? Java与C++之间有一堵由内存动态分配和垃圾回收机制所围成的高墙,墙 ...
- python使用argparse 、paramiko实现服务器管理器
使用argparse,paramiko两个包去实现简易的服务器管理器,完成两种方式的连接( 密码和密钥 ),以及命令行交互,文件上传下载. 相比sys.argv的方式去判断传入的参数,如果参数较多那么 ...
- 贪心-Course Schedule III
2020-02-01 21:37:39 问题描述: 问题求解: 对于课程来说截止时间在前面的肯定需要优先安排,所以首先需要将courses按照deadline进行排序. 然后只需要不断的加入当前的课程 ...
- 全屏banner及全屏轮播
一.全屏banner 1.设置网页图片全屏banner <!DOCTYPE html> <html lang="en"> <head> < ...
- Springcloud config + zuul 搭建动态网关
1,实现的效果,就是zuul 网关的配置路由实现负载均衡,zuul 的配置文件放在springcloud config 上 2,需要的服务如下: 3,其实就是配置下springcloud-zuul 的 ...
- Redis 集群--------Redis-cluster
1集群方案 1.官方方案redis-cluster搭建实战 2.客户端分片技术(不推荐),扩容/缩容时,必须手动调整分片程序,出现故障不能自动转移 3.可以使用主从复制方式(不推荐) 4.使用一些代理 ...
- 使用Git pull文件时,出现"error: RPC failed; curl 18 transfer closed with outstanding read data remaining"
error: RPC failed; curl transfer closed with outstanding read data remaining fatal: The remote end h ...
- BurpSuit工具安装和基本使用方法
burpsuite是渗透的必备工具,使用它可以进行一些截包分析,修改包数据.暴力破解.扫描等功能,使用最多的场景应该是设置代理拦截数据包分析数据和爆破. JDK工具下载和安装(可选) 运行BurpSu ...