miller_rabin素性测试

本文介绍了一种高效的素数检测方法——Miller-Rabin算法,并实现了一个完整的C++程序来验证该算法的有效性。此外,还展示了如何利用快速幂算法进行大数运算,以提高素数检测的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值