首页 > 代码库 > hdu2138 Miller_Rabin

hdu2138 Miller_Rabin

 

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 32-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和n个int32整数,询问其中有多少个质数,有多组数据

 

【题解】

有的时候我们需要快速判断一个数是不是质数

这时候我们需要使用miller-rabin算法

首先,根据费马小定理

我们认识到若p是质数

则a^p=a(mod p)

于是我们使用一个推广的结论

“记n=a*2^b,在[1,n)中随机选取一个整数x,如果x^a ≡1或x^(a*2^i) ≡-1(其中0<=i<b),那么我们认为n是质数。”——ysy

如果这样判断,我们会发现有1/4的概率出错

我们多判断几次即可

除非你是宇宙无敌非洲人

#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<queue>
#include<map>
#include<vector>
#include<set>
#define il inline
#define re register
using namespace std;
typedef long long ll;
int T;
ll n,ans=0,a,b;
il int ran(){
    return rand()*rand()+rand();
}
il ll pow(ll base,ll pow){
    ll ans=1;
    for(;pow;pow>>=1){
        if(pow&1) ans=ans*base%n;
        base=base*base%n;
    }
    return ans;
}
il bool chk(){
    ll x=ran()%(n-1)+1,now=pow(x,a);
    if(now==1) return true;
    for(int i=0;i<b;i++){
        if(now==n-1) return true;
        now=now*now%n;
    }
    return false;
}
il bool isprime(){
    a=n-1;b=0;
    while(a%2==0){
        a/=2;b++;
    }
    for(int i=1;i<=100;i++)
        if(!chk()) return false;
    return true;
}
il void init(){
    srand(T);ans=0;
    for(int i=1;i<=T;i++){
        cin>>n;
        ans+=isprime();
    }
    cout<<ans<<endl;
}
int main(){
    while(scanf("%d",&T)!=EOF){
        init();
    }
    return 0;
}

 

hdu2138 Miller_Rabin