题目链接:http://poj.org/problem?id=3641
题目大意:根据已a为基的伪素数的定义,判断p是否是已a为基的伪素数。(p为合数且满足a^p mod p = a), p<10^9
解题思路:p<10^9,用普通素数判定即可通过,去模运算用快速幂实现。
参考代码:
#include
#include
#include
#include
上面这道题似乎与题目Miller-Rabin素数测试没有关系哈,下面就给个代码应用Miller-Rabin素数测试判断大的整数n(10^14或者更大)是否为素数.
#include
#include
#include
#include
改进Miller-Rabin素数测试
似乎Miller-Rabin素数测试已无瑕疵,然而有一类卡迈尔数,将导致Miller-Rabin素数测试出现错误。
定义: 一个合数n,若对于所有满足(b,n)=1的正整数b都有b^n-1=1(mod n) 成立,则成n为卡迈尔数。
那么如何改进上述算法,以排除卡迈尔数呢?首先介绍二次探测定理。
二次探测定理: 如果p是一个素数,且0<x<p,则方程x^2%p=1的解为x=1或x=p-1.
那么可以根据二次探测定理,再利用费马小定理计算b^n-1%的过程中增加对整数n的二次探测,一旦发现违背二次探测条件,即得出n不是素数的结论。
算法实现:(增加一个witness(),改写一下Miller_rabin())
bool Witness(ll a,ll n)
{
ll m=n-1;
int j=0;
while(!(m&1)){
j++;
m>>=1;
}
ll x=quickpow_mod(a,m,n);
if(x==1||x==n-1) return false;
while(j--){
x=x*x%n;
if(x==n-1)return false;
}
return true;
}
bool Miller_rabin(ll n)
{
if(n < 2) return false;
else if(n == 2) return true;
else if(!(n&1)) return false;
for(int i=0;i < N; i++){
ll a =random(n-2) + 1;
if( Witness ( a , n ) ) return false;
}
return true;
}