一.引用原因:
在数据范围在LL类型之中,N_maxLL=1e18,即使在O(sqrt(n))的时间复杂度之内也不能够满足要求,这时候我们可以对其进行 Miller-Rabin 素数测试,可以大概率测出其是否为素数,大部分情况下是正确的;
二.理论基础:
(1)费马小定理:当 为质数,有 ,不过反过来不一定成立,也就是说,如果 , 互质,且 ,不能推出 是质数;
(2)二次探测:如果 是一个素数,, 则方程 的解为 或 ;
三.算法实现:
思路来源:https://vjudge.net/problem/HihoCoder-1287这里面有详细的介绍;
(1)快速幂运算||快速乘运算:两者结合效率更大;参考我写的模板:https://blog.csdn.net/queque_heiya/article/details/105929064
(2)Miller_Rabin算法实现即可;
bool Miller_Rabin(LL n){//判断素数
LL u=n-1,pre,x;
int i,j,k=0;
if(n==2||n==3||n==5||n==7||n==11) return true;
if(n==1||(!(n%2))||(!(n%3))||(!(n%5))||(!(n%7))||(!(n%11))) return
false;//初始化判断素数
for(;!(u&1);k++,u>>=1);//按照要求转换形式
for(i=0;i<5;i++){
x=rand()%(n-2)+2;//生成随机数
x=pow_mod(x,u,n);
pre=x;
for(j=0;j<k;j++){
x=mul_mod(x,x,n);
if(x==1&&pre!=1&&pre!=(n-1))//二次探测判断
return false;
pre=x;
}
if(x!=1) return false;//用费马小定理判断
}
return true;
}
四.相关题目:
LibreOJ - 143 https://blog.csdn.net/queque_heiya/article/details/105929206
HihoCoder - 1287 https://blog.csdn.net/queque_heiya/article/details/105929149