HDU_2138_How many prime numbers

How many prime numbers

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 18969    Accepted Submission(s): 6484


Problem 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
 

Author
wangye
 

Source

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

#include <iostream>
#include <string>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <climits>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
typedef long long           LL ;
typedef unsigned long long ULL ;
const int    maxn = 1000 + 10  ;
const int    inf  = 0x3f3f3f3f ;
const int    npos = -1         ;
const int    mod  = 1e9 + 7    ;
const int    mxx  = 100 + 5    ;
const double eps  = 1e-6       ;

LL pow_mod(LL x, LL k, LL m){
	LL r=1%m;
	while(k){
		if(1&k)r=((r*x)%m + m)%m;
		x=((x*x)%m + m)%m;
		k>>=1;
	}
	return r;
}
int testprime(LL x, LL a, LL d){
	if(2==x)return 1;
	if(a==x)return 1;
	if(!(1&x))return 0;
	while(!(1&d))d>>=1;
	LL t=pow_mod(a,d,x);
	while((d!=x-1) && (1!=t) && (t!=x-1)){
		t=(LL)(t*t%x + x)%x;
		d<<=1;
	}
	return (t==x-1 || 1==(1&d));
}
int isprime(LL x){
	if(x<2)return 0;
	LL a[]={2,3,61};
	for(int i=0;i<3;i++)
		if(!testprime(x,a[i],x-1))
			return 0;
	return 1;
}
LL x;
int n, ans;
int main(){
	// freopen("in.txt","r",stdin);
	// freopen("out.txt","w",stdout);
	while(~scanf("%d",&n)){
		ans=0;
		while(n--){
			scanf("%lld",&x);
			ans+=isprime(x);
		}
		printf("%d\n",ans);
	}
	return 0;
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值