\(Miller-Rabin\)​素数测试

用途

判断整数\(n\)是否是质数,在\(n\)较小的情况下,可以使用试除法,时间复杂度为\(O(\sqrt n)\)。但当\(n\)的值较大的时候,朴素的试除法已经不能在规定时间内解决问题。此时,我们可以用\(Miller-Rabin\)素数测试算法,时间复杂度可以降低至\(O(\log_2n)\)。

引理

费马小定理

若\(a,p \in \mathbb{Z}\),\(p\)为质数,则

\[a^{p-1} \equiv 1(mod\;p)
\]

在此不给出证明。

二次探测定理

描述

若\(a,p \in \mathbb{Z}\),\(a^{2} \equiv 1(mod\;p)\),\(p\)为质数,则\(a \equiv 1(mod\;p)\)或\(a \equiv p-1(mod\;p)\)。

证明

\[\begin{aligned}
&\because a^{2} \equiv 1(mod\;p)\\
&\therefore p \mid (a^{2}-1)\\
&\therefore p \mid (a+1)(a-1)\\
&\because p为质数\\
&\therefore p \mid (a+1) 或(a-1)\\
&\therefore a+1 \equiv 0(mod\;p)或a-1 \equiv 0(mod\;p)\\
&\therefore a \equiv 1 (mod\;p)或a \equiv p-1 (mod\;p)\\
\end{aligned}
\]

过程

根据费马小定理,我们可以得到一个真命题:若\(p\)为质数,则\(a^{p-1} \equiv 1(mod\;p)\)。我们考虑这一命题的逆命题:若\(a^{p-1} \equiv 1\),则\(p\)为质数。我们会惊讶地发现,这一逆命题在大多数情况下竟然成立。也就是说,我们得到了一种有效地判断质数的方法,即取一个底数\(a\),判断它与所需判断的数\(p\)是否满足这一等式。尽管有时可能出错,但这一算法的效率相比起朴素算法来说有了很大的提升。

接下来我们要做的就是提高这一算法的正确性。首先想到的自然是取多个\(a\)值,在常见的题目中,取\([2,29]\)大概就能通过测试,当然也可以随机生成,注意\(a\)的值应该小于\(p\)。第二个优化是基于二次探测定理的。设\(p=2^nm+1\),则可先算出\(a^m\),然后再平方\(n\)次,求得\(a^{p-1}\)。在这一过程中,若某次平方后所得的结果为\(1\)但上次平方后的结果不等于\(p-1\)或\(1\),就出现了矛盾,从而就不满足\(p\)为质数这一前提。最后再次判断是否满足等式即可。

注意乘法可能越界,应拆成类似快速幂的算法。

代码

const int prime[10]={2,3,5,7,11,13,17,19,23,29};
long long multi(long long a,long long b,long long p)
{
long long t=0;
while(b)
{
if(b&1)
t=(t+a)%p;
a=(a<<1)%p;
b>>=1;
}
return t;
}
long long power(long long a,long long b,long long p)
{
long long t=1;
while(b)
{
if(b&1)
t=multi(t,a,p);
a=multi(a,a,p);
b>>=1;
}
return t;
}
bool Miller_Rabin(long long x)
{
if(x==2)
return true;
if(!(x&1)||x<2)
return false;
long long t=x-1,exponent=0;
while(!(t&1))
{
t>>=1;
++exponent;
}
for(int i=0;i<10&&prime[i]<x;++i)
{
long long m=power(prime[i],t,x);
for(int j=0;j<exponent;++j)
{
long long n=multi(m,m,x);
if(n==1&&m!=1&&m!=x-1)
return false;
m=n;
}
if(m!=1)
return false;
}
return true;
}

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. 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 ...

  3. Miller Rabin素数检测与Pollard Rho算法

    一些前置知识可以看一下我的联赛前数学知识 如何判断一个数是否为质数 方法一:试除法 扫描\(2\sim \sqrt{n}\)之间的所有整数,依次检查它们能否整除\(n\),若都不能整除,则\(n\)是 ...

  4. POJ2429_GCD &amp; LCM Inverse【Miller Rabin素数測试】【Pollar Rho整数分解】

    GCD & LCM Inverse Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 9756Accepted: 1819 ...

  5. Miller-Rabin素数测试算法(POJ1811Prime Test)

    题目链接:http://poj.org/problem?id=1811 题目解析:2<=n<2^54,如果n是素数直接输出,否则求N的最小质因数. 求大整数最小质因数的算法没看懂,不打算看 ...

  6. POJ1811_Prime Test【Miller Rabin素数測试】【Pollar Rho整数分解】

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

  7. 素数测试算法(基于Miller-Rabin的MC算法) // Fermat素数测试法

    在以往判断一个数n是不是素数时,我们都是采用i从2到sqrt(n)能否整除n.如果能整除,则n是合数;否则是素数.但是该算法的时间复杂度为O(sqrt(n)),当n较大时,时间性能很差,特别是在网络安 ...

  8. Miller Rabin素数检测

    #include<iostream> #include<cstdio> #include<queue> #include<cstring> #inclu ...

  9. Miller-Rabbin随机性素数测试算法

    //**************************************************************** // Miller_Rabin 算法进行素数测试 //速度快,而且 ...

随机推荐

  1. js基础——面向对象(构造函数)

    1.面向对象:类的标志,通过类可创建多个具有相同属性和方法的对象 2.创建对象 1)工厂模式方式:避免重复实例化但未能解决识别问题  function boss(name, age) {       ...

  2. Codeforces Beta Round #4 (Div. 2 Only) D. Mysterious Present(LIS)

    传送门 题意: 现在我们有 n 个信封,然后我们有一张卡片,并且我们知道这张卡片的长和宽. 现给出这 n 个信封的长和宽,我们想形成一个链,这条链的长度就是这条链中所含有的信封的数量: 但是需要满足① ...

  3. 微软软件开发技术二十年回顾-API篇(转)

    二. API篇 随着Windows操作系统开始占据主导地位,开发Windows平台下的应用程序成为人们的需要.当然,这也为传统的DOS程序员提供了一种新的编程方法-一种不受设备限制并由事件驱动的编程方 ...

  4. Django框架之中间件MiddleWare

    Django中的中间件是一个轻量级.底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出.中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健 ...

  5. JAVA8学习——深入浅出Lambda表达式(学习过程)

    JAVA8学习--深入浅出Lambda表达式(学习过程) lambda表达式: 我们为什么要用lambda表达式 在JAVA中,我们无法将函数作为参数传递给一个方法,也无法声明返回一个函数的方法. 在 ...

  6. Laravel5.5 邮件发送报错:stream_socket_client()

    具体报错如下: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages: error:1409 ...

  7. 最小生成树+LCA不能算最小环!!!!!!!

  8. 010 Ceph RGW对象存储

    一.对象存储 1.1 介绍 通过对象存储,将数据存储为对象,每个对象除了包含数据,还包含数据自身的元数据 对象通过Object ID来检索,无法通过普通文件系统操作来直接访问对象,只能通过API来访问 ...

  9. tomcat 配置项目前缀(推荐方式四)

    一. 显示配置 Context 的 path   需要在 server.xml 文件中手动配置. <Host name="localhost" appBase="w ...

  10. 【题解】BZOJ1034 [ZJOI2008]泡泡堂BNB(贪心)

    [题解]BZOJ1034 [ZJOI2008]泡泡堂BNB(贪心) 考虑直接模拟田忌赛马... 我的最小比你的大,直接上 我的最大比你的大,直接上 otherwise,我小换你大 考虑最劣,由于每次比 ...