模板--Miller-Rabin素数测试算法

一.引用原因:

在数据范围在LL类型之中,N_maxLL=1e18,即使在O(sqrt(n))的时间复杂度之内也不能够满足要求,这时候我们可以对其进行 Miller-Rabin 素数测试,可以大概率测出其是否为素数,大部分情况下是正确的;

二.理论基础:

(1)费马小定理:当 p 为质数,有 a^{p-1}\equiv 1(mod \: \, p),不过反过来不一定成立,也就是说,如果 a , p 互质,且 a^{p-1}\equiv 1(mod \: \, p),不能推出 p 是质数;

(2)二次探测:如果 p 是一个素数,0 < x < p, 则方程 x^{2}\equiv 1(mod\: \, p) 的解为 x = 1 或 x = p - 1;

三.算法实现:

思路来源: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

猜你喜欢

转载自blog.csdn.net/queque_heiya/article/details/105928679