ACM入门之Miller-Rabin素数测试算法
Posted 辉小歌
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ACM入门之Miller-Rabin素数测试算法相关的知识,希望对你有一定的参考价值。
参考博文:https://blog.csdn.net/forever_dreams/article/details/82314237
模板来自参考博文
这个算法可以大概率的判断一个数是不是质数。时间复杂度是O(T×logN)
(T为检测轮数)
这里只列出模板,因为一般不常用。
#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
int prime[15]=2,3,5,7,11,13,17,19,23,29,31,37,41,43,47;
LL Quick_Multiply(LL a,LL b,LL c) //快速积(和快速幂差不多)
LL sum=0;
while(b)
if(b&1) sum=(sum+a)%c;
b>>=1;
a=(a+a)%c;
return sum;
LL Quick_Power(LL a,LL b,LL c) //快速幂,这里就不赘述了
LL ans=1,res=a;
while(b)
if(b&1) ans=Quick_Multiply(ans,res,c);
b>>=1;
res=Quick_Multiply(res,res,c);
return ans;
bool Miller_Rabin(LL x) //判断素数
LL i,j,k;
LL s=0,t=x-1;
if(x==2) return true; //2是素数
if(x<2||!(x&1)) return false; //如果x是偶数或者是0,1,那它不是素数
while(!(t&1)) //将x分解成(2^s)*t的样子
s++;
t>>=1;
for(i=0;i<15&&prime[i]<x;++i) //随便选一个素数进行测试
LL a=prime[i];
LL b=Quick_Power(a,t,x); //先算出a^t
for(j=1;j<=s;++j) //然后进行s次平方
k=Quick_Multiply(b,b,x); //求b的平方
if(k==1&&b!=1&&b!=x-1) //用二次探测判断
return false;
b=k;
if(b!=1) return false; //用费马小定律判断
return true; //如果进行多次测试都是对的,那么x就很有可能是素数
int main()
int t; cin>>t;
while(t--)
LL x; cin>>x;
if(Miller_Rabin(x)) puts("Yes");//是质数
else puts("No");
return 0;
以上是关于ACM入门之Miller-Rabin素数测试算法的主要内容,如果未能解决你的问题,请参考以下文章