由费马小定理可知,若n为素数,且a是整数,则满足a^n≡a(mod n)。若存在正整数a不满足a^n≡a(mod n),那么n是合数。
定义:令a是一正整数,若n是合数且满足a^n≡a(mod n),则n称为以a为基的伪素数。
算法原理:Miller-Rabin素数测试算法基于费马小定理:假如n是素数,且gcd(a,n)=1,那么a^(n-1)≡1(mod n)。如果a^(n-1)≡1(mod n)(a为任意小于n的正整数),则可近似认为n为素数,取多个底进行试验,次数越多,n为素数的概率越大。
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
typedef long long int64;
#define TIMES 5
int64 random(int64 n)
{
return (int64)((double)rand()/RAND_MAX*n+0.5);
}
int64 multi(int64 a,int64 b,int64 m) //a*b%m
{
int64 ans=0;
while(b)
{
if(b&1)
ans=(ans+a)%m;
b>>=1;
a=(a<<1)%m;
}
return ans;
}
int64 kpow(int64 x,int64 n,int64 m) //x^n%m
{
int64 ans=1;
while(n)
{
if(n&1)
ans=multi(ans,x,m);
n>>=1;
x=multi(x,x,m);
}
return ans;
}
bool miller_rabin(int64 n)
{
for(int64 i=1;i<=TIMES;i++)
{
int64 x=random(n-2)+1;
if(kpow(x,n-1,n)!=1)
return false;
}
return true;
}
int main()
{
int64 x;
while(cin>>x)
{
if(miller_rabin(x))
cout<<"YES\n";
else
cout<<"NO\n";
}
return 0;
}
题目:http://poj.org/problem?id=3641