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素数测试算法的主要内容,如果未能解决你的问题,请参考以下文章

记一次使用快速幂与Miller-Rabin的大素数生成算法

浅谈Miller-Rabin素数检测算法

Miller-Rabin素数测试

Miller-Rabin素数测试

Miller-Rabin算法 codevs 1702 素数判定 2

Miller-Rabin素数检测算法