SDNU 1490.Problem_H Miller_Rabin算法判断素数


1490.Problem_H

Time Limit: 3000 MS    Memory Limit: 32768 KB

Description

Give you a lot of positive integers, just to find out how many prime numbers there are.


Input

There are a lot of cases. In each case, there is an integer N representing the number of integers to find. Each integer won’t exceed 64-bit signed integer, and each of them won’t be less than 2.


Output

For each case, print the number of prime numbers you have found out.


Sample Input

3
2 3 4

Sample Output

2


    题意是说给出n个数,问这几个数中有几个素数,然而范围没给说清= =这是选拔赛的一道题,用线性筛选的方法会超时,所以用的队友的板子敲的Miller_Rabin算法,结果一直在RE,到比赛结束也没能找出问题。

    现在重新拿出来看,因为之前遇到素数的问题一直都是用线性筛选处理的,所以对这个算法其实我了解的并不多= =这是一种用随机数来进行判断的方法,虽然存在出现错误的可能,但是这个概率非常小,所以可以忽略不计。而在调用这个算法的时候,队友的板子里用到了srand()这个函数,当时选拔赛的环境是G++,而G++中不可以使用这个函数,所以一直在RE,将这句去掉之后就可以A了......好吧,然后再去OJ上交C++的环境就可以过了。代码是敲的队友板子也没什么多说的。

    下面AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<time.h>
using namespace std;
const int S=8;

long long mult_mod(long long a,long long b,long long c)
{
    a%=c;
    b%=c;
    long long ret=0;
    long long tmp=a;
    while(b)
    {
        if(b&1)
        {
            ret+=tmp;
            if(ret>c)
                ret-=c;
        }
        tmp<<=1;
        if(tmp>c)
            tmp-=c;
        b>>=1;
    }
    return ret;
}

long long pow_mod(long long a,long long n,long long mod)
{
    long long ret=1;
    long long temp=a%mod;
    while(n)
    {
        if(n&1)
            ret=mult_mod(ret,temp,mod);
        temp=mult_mod(temp,temp,mod);
        n>>=1;
    }
    return ret;
}

bool check(long long a,long long n,long long x,long long t)
{
    long long ret=pow_mod(a,x,n);
    long long last=ret;
    for(int i=1;i<=t;i++)
    {
        ret=mult_mod(ret,ret,n);
        if(ret==1&&last!=1&&last!=n-1)
            return true;
        last=ret;
    }
    if(ret!=1)
        return true;
    else
        return false;
}

bool Miller_Rabin(long long n)
{
    if(n<2)
        return false;
    if(n==2)
        return true;
    if((n&1)==0)
        return false;
    long long x=n-1;
    long long t=0;
    while((x&1)==0)
    {
        x>>=1;
        t++;
    }
    srand(time(NULL));
    for(int i=0;i<S;i++)
    {
        long long a=rand()%(n-1)+1;
        if(check(a,n,x,t))
            return false;
    }
    return true;
}

long long factor[100];
int tol;

long long gcd(long long a,long long b)
{
    long long t;
    while(b)
    {
        t=a;
        a=b;
        b=t%b;
    }
    if(a>=0)
        return a;
    else
        return -a;
}

int main()
{
    int T;
    long long n,ans;
    while(scanf("%d",&T)!=EOF)
    {
        ans=0;
        while(T--)
        {
            scanf("%I64d",&n);
            if(Miller_Rabin(n))
                ans++;
        }
        cout<<ans<<endl;
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值