#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef long long LL;
LL mul(LL a,LL b,LL mod) //一个LL*LL的黑科技
{
LL tmp=(a*b-(LL)((long double)a/mod*b+1e-8)*mod);
return tmp<0?tmp+mod:(tmp>=mod?tmp-mod:tmp); //就是取mod
}
LL qkpow(LL a,LL p,LL mod) //快速幂
{
LL t=1,tt=a%mod;
while(p)
{ //若p为奇数,则
if(p&1)t=mul(t,tt,mod); //所有乘法都要用这个厉害的乘法
tt=mul(tt,tt,mod);
p>>=1;
}
return t;
}
bool Miller_Rabin(LL n) //可能是素数就返回true,任何一个测试不通过就不是素数,返回false
{
if(n==2)return true;
if(n<2 || ~n&1)return false;//先要特判排除两种情况。若n取反后与1的值为真,说明n是偶数,要返回false,过滤掉。
LL r=n-1,d=0,a,x,xx; //x是前一次的值,xx是当前值
while(~r&1)d++,r>>=1; //若r为偶数,d++,r右移一位。r=r/2;循环下去。
for(int i=1;i<=10;i++)
{
a=rand()%(n-2)+2; //产生随机数a测试。a的取值范围是[2,n-1]
x=qkpow(a,r,n);
for(int k=1;k<=d;k++) //直接默认从序列第二个元素开始,因此只循环d次
{
xx=mul(x,x,n); //所有乘法都要用这个厉害的乘法
if(xx==1 && x!=1 && x!=n-1)return false;//二次探测定理
x=xx;
}
if(xx!=1)return false;
}
return true;
}
int main()
{
LL n;
while(cin>>n)
Miller_Rabin(n)?printf("Y\n"):printf("N\n");
return 0;
}miller_rabin素性测试
最新推荐文章于 2024-02-01 15:09:49 发布
本文介绍了一种高效的素数检测方法——Miller-Rabin算法,并实现了一个完整的C++程序来验证该算法的有效性。此外,还展示了如何利用快速幂算法进行大数运算,以提高素数检测的效率。
7922

被折叠的 条评论
为什么被折叠?



