与数论的厮守01:素数的测试——Miller Rabin
看一个数是否为质数,我们通常会用那个O(√N)的算法来做,那个算法叫试除法。然而当这个数非常大的时候,这个高增长率的时间复杂度就不够这个数跑了。
为了解决这个问题,我们先来看看费马小定理:若n为素数,a与n互质,则an-1Ξ1(mod n)。于是有人想过把它倒过来判断n是否为素数。首先,若a与n不互质,那么n为合数。所以只需要满足an-1Ξ1(mod n)即可,这个a干脆就让它等于2了。即判断2n-1Ξ1(mod n)是否成立。若不成立,那么n必定为合数。但成立时n就是素数吗?又有人找出了个数:2340Ξ1(mod 341),但是发现341是合数(11*31)。那我们能不能直接把a换成另一个数呢?答案是否定的。因为对于所有a,都存在an-1Ξ1(mod n),其中n为合数。于是这个方法就出错了。但是紧接着Miller Rabin测试对这个方法进行了改进。
Miller Rabin的依据是,当n为素数时,x2Ξ1(mod n)的根有两个:x=1和x=n-1。这个根叫做平凡平方根(真的拗口)。因此,如果对于模n存在1的非平凡平方根,则n是个合数。
那么Miller Rabin怎么改进的呢?
①选取多个基数a;
②寻找模n为1的非平凡平方根:令2t*u=n-1(t>=1,u为奇数),则an-1=a2t*u=(au)2t。先算出x=au mod n,再把x平方t次,每次模上n,这样我们就得到了一个长度为t+1的序列。我们希望这个序列以1结尾,并且若某一项为1,则前一项必须为1或n-1,否则n就是合数。
这并不是简单地验证一下费马小定理。Miller Rabin会对一个数进行s次测试,其出错率低至2-s。
然后是代码(喜人的rand):
#include <cstdio>
#include <cstdlib>
#include <ctime>
using namespace std; inline long long pow(long long a, long long b, long long p){
long long ans = % p;
while(b){
if(b & ) ans = ans * a % p;
a = a * a % p;
b >>= ;
}
return ans;
} inline bool judge(long long n, long long a){
long long u = , t = n - ;
while(t % == ) u++, t /= ;
long long x = pow(a, t, n);
for(long long i = ; i <= u; i++){
long long next = x * x % n;
if(next == && x != && x != n - ) return true;
x = next;
}
return x == ? false : true;
} inline bool rabin(long long n){
if(n == ) return true;
if(n < || n % == ) return false;
for(long long i = ; i <= ; i++){
long long a = rand() % (n - ) + ;
if(judge(n, a)) return false;
}
return true;
} int main(){
srand(time());
long long t, in;
scanf("%lld", &t);
while(t--){
scanf("%lld", &in);
printf("%s\n", rabin(in) ? "yes" : "no");
}
return ;
}
据说重庆OI出过一道Miller Rabin的题。
总结:
要点1.Miller Rabin是将费马小定理倒转过来,验证n是否存在非平凡平方根.
要点2.平凡平方根:x2Ξ1(mod n),x=1或x=n-1
要点3.对于基数a的判断基于倍增的思想.
与数论的厮守01:素数的测试——Miller Rabin的更多相关文章
- 关于素数:求不超过n的素数,素数的判定(Miller Rabin 测试)
关于素数的基本介绍请参考百度百科here和维基百科here的介绍 首先介绍几条关于素数的基本定理: 定理1:如果n不是素数,则n至少有一个( 1, sqrt(n) ]范围内的的因子 定理2:如果n不是 ...
- 【数论基础】素数判定和Miller Rabin算法
判断正整数p是否是素数 方法一 朴素的判定
- Miller Rabin 大素数测试
PS:本人第一次写随笔,写的不好请见谅. 接触MillerRabin算法大概是一年前,看到这个算法首先得为它的神奇之处大为赞叹,竟然可以通过几次随机数据的猜测就能判断出这数是否是素数,虽然说是有误差率 ...
- POJ1811_Prime Test【Miller Rabin素数测试】【Pollar Rho整数分解】
Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29193 Accepted: 7392 Case Time ...
- 与数论的厮守02:整数的因子分解—Pollard_Rho
学Pollard_Rho之前,你需要学会:Miller Rabin. 这是一个很高效的玄学算法,用来对大整数进行因数分解. 我们来分解n.若n是一个素数,那么就不需要分解了.所以我们还得能够判断一个数 ...
- HDU1164_Eddy'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 ...
- POJ2429_GCD & LCM Inverse【Miller Rabin素数測试】【Pollar Rho整数分解】
GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9756Accepted: 1819 ...
- POJ1811_Prime Test【Miller Rabin素数測试】【Pollar Rho整数分解】
Prime Test Time Limit: 6000MS Memory Limit: 65536K Total Submissions: 29193 Accepted: 7392 Case Time ...
- Miller Rabin素数检测与Pollard Rho算法
一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...
随机推荐
- 怎么让Windows2012和Windows2008多用户同时远程
具体方法请参照百度经验:http://jingyan.baidu.com/article/cd4c2979f19765756e6e60ec.html.经过实践证明,是没有问题的.
- class ObjectOutputStream也是过滤流,使节点流直接获得输出对象。
class ObjectOutputStream也是过滤流,使节点流直接获得输出对象. 最有用的方法:WriteObject(Object b) 用流传输对象称为对象的序列化,但并不使所有的对象都可以 ...
- DeBug Python代码全靠print函数?换用这个一天2K+Star的工具吧,改进版
pysnooper是代码debug神器,比无限low print好很多和也比日志debug好一些,比断点调试也好一些,这个很犀利的装饰器. https://www.toutiao.com/a66829 ...
- 关于SpringBoot 2.0,Pageable 无法注入,提示缺少默认构造方法的解决办法
在SpringBoot 2.0 以前,我们会配置以下类 * @date 2018/06/03 */ @Configuration public class WebMvcConfig extends W ...
- [学习笔记]nodejs全局安装和本地安装的区别
参考来源于 nodejs全局安装和本地安装的区别 1.全局安装 $ npm install gulp --global 2.作为项目的开发一开(devDependencies)安装 $ npm ins ...
- 动态性能视图v$mystat,v$sesstat,v$statname
视图说明: v$mystat-------> 当前会话统计 v$sesstat------> 按会话进行分组统计 v$sysstat-------> 当系统的整体统计 v$statn ...
- CSS设置浏览器滚动条样式
/*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ ::-webkit-scrollbar { width: 5px; height: 110px; background-color: #F5 ...
- ubuntu中安装blogPost
1.实验环境 Ubuntu16.04x86 2.安装blogPost步骤 2.1 安装方式比较简单,打开ubuntu软件中心 2.2 搜索DB Browser for SQLite,点击安装即可 上图 ...
- Solve Docker for Windows error: docker detected, A firewall is blocking file Sharing between Windows and the containers
被这个“分享硬盘”问题烦了我好几个小时,终于在一个叫Marco Mansi外国人博客上找到解决方法了,真的很无奈 https://blog.olandese.nl/2017/05/03/solve-d ...
- Jquery 获取 radio选中值,select选中值
随着Jquery的作用越来越大,使用的朋友也越来越多.在Web中,由于CheckBox.Radiobutton .DropDownList等控件使用的频率比较高,就关系到这些控件在Jquery中的操作 ...