How many prime numbers HDU - 2138 (Miller-Rabin测试)

本文介绍了一种使用Miller-Rabin测试的高效素数检测算法。通过将N-1分解并进行随机测试,可以高精度判断一个数是否为素数。文章提供了C++实现代码,展示了如何运用此算法解决特定问题。

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

传送门

题意:给出一组数,测试这组数一共有多少个素数

题解:要测试N是否为素数,首先将N-1分解为(2^s)*d。在每次测试开始时,先随机选一个介于[1,N-1]的整数a,如果对所有的r属于[0,s-1]都满足a^dmodN不等于1&&a^((2^r)*d)modN不等于-1,则N是合数,否则,N有3/4的几率为素数。为了提高测试的正确性,可以选择不同的a进行多次测试。

附上代码:



#include<bits/stdc++.h>

using namespace std;

//Miller-Rabin测试
//复杂度O(logn)
typedef long long ll;

ll pow_mod(ll a,ll i,ll n)
{
    if(i==0){
        return 1%n;
    }
    ll temp=pow_mod(a,i>>1,n);
    temp=temp*temp%n;
    if(i&1){
        temp=temp*a%n;
    }
    return temp;
}

bool test(ll n,ll a,ll d)
{
    if(n==2){
        return true;
    }
    if(n==a){
        return true;
    }
    if((n&1)==0){
        return false;
    }
    while(!(d&1)){
        d=d>>1;
    }
    ll t=pow_mod(a,d,n);
    while((d!=n-1)&&(t!=1)&&(t!=n-1)){
        t=(ll)t*t%n;
        d=d<<1;
    }
    return (t==n-1||(d&1)==1);
}

bool isprime(ll n)
{
    if(n<2){
        return false;
    }
    int a[]={2,3,61};
    for(int i=0;i<=2;i++){
        if(!test(n,a[i],n-1)){
            return false;
        }
    }
    return true;
}

int main()
{
    ll n,temp;
    while(scanf("%lld",&n)!=EOF){
        ll res=0;
        for(int i=0;i<n;i++){
            scanf("%lld",&temp);
            if(isprime(temp)){
                res++;
            }
        }
        printf("%lld\n",res);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值