感觉这就是一个多次随机的算法……
算法
嗯,随机大法好,在一般判断素数中主要有这几种:暴力枚举判断法(判断一个:O(√n)),杜氏筛(O(nloglogn),欧拉筛(n)等,这里说一个随机筛法:Miller–Rabin,这玩意主要靠两条定理,一是费马小定理,二是二次探测定理,以下说一下算法流程:
对于一个p来说,
1.随即去一个a。
2.若a^(p-1)%p!=1,则这是一个合数,退出
3.若a^(p-1)%p==1,则这个数说不定是质数
4.返回1
这是一个不错的思路,然而,依旧有一些合数会被判做质数,这类数是强伪素数,所以,我们要用二次探测定理。
二次探测定理:如果p是一个素数,且0<x<p,则方程x^2≡1(mod p)的解为x=1或p-1。这就很棒了,注明对于步骤一多多益善。
上代码
#include<bits/stdc++.h>
using namespace std;
long long x;
long long power(long long a,long long b){
long long r=1;
a=a%x;
while(b){
if(b%2) r=r*a%x;
a=a*a%x;
b/=2;
}
return r%x;
}
int main(){
cin>>x;
if(x==1){
printf("NO\n");
return 0;
}
if(x==2){
printf("YES\n");
return 0;
}
if(x%2==0){
printf("NO\n");
return 0;
}
srand(time(NULL));
for(int i=1;i<=1000;i++){
long long y=rand(),k=x-1;
if(power(y%x,x)!=y%x){
printf("NO\n");
return 0;
}
while(k==(k/2)*2){
long long l=power(y,k);
if(l==x-1){
printf("YES\n");
return 0;
}
if(l==1) k/=2;
else{
printf("NO\n");
return 0;
}
}
}
printf("YES\n");
return 0;
}