HDU 5901 Count primes 2016年沈阳网络赛 (Lehmer素数计数)

来源:互联网 发布:java 开发规范 编辑:程序博客网 时间:2024/06/05 05:48

Count primes

Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 155    Accepted Submission(s): 28

Problem Description
Easy question! Calculate how many primes between [1...n]!
Input
Each line contain one integer n(1 <= n <= 1e11).Process to end of file.
Output
For each case, output the number of primes in interval [1...n]
Sample Input
2310
Sample Output
124
Source
2016 ACM/ICPC Asia Regional Shenyang Online
Recommend
wange2014   |   We have carefully selected several similar problems for you:  5900 5899 5898 5897 5896 

题解:  Meissel-Lehmer算法。Lehmer素数计数。可以计数到1000亿!!由我来卡全场!easyquestion,说得跟真的似的。(:其实是真的,只是我太菜了....

AC代码:
//1010 by Walker#include<bits/stdc++.h>using namespace std;typedef long long ll;const ll MAXN = 10000000;ll N;bool isp[MAXN];int pcnt[MAXN];vector<int> primes;void init(){  for(int i=2; i<MAXN; i++){  isp[i] = true;  }      for(int i=2; i<MAXN; i++) {    if(!isp[i]) continue;    primes.push_back(i);    for(int j=2*i; j<MAXN; j+=i){    isp[j] = false;}         }   pcnt[0] = 0;   for(int i=1; i<MAXN; i++){     pcnt[i] = pcnt[i-1] + isp[i];   }     }ll prime_count(ll lim);ll phi(ll m, int n){  if(m <= 0) return 0;  if(n == 0) return m;  if(primes[n-1] * primes[n-1] >= m) return prime_count(m) - n + 1;  return phi(m, n-1) - phi(m / primes[n-1], n-1);}ll prime_count(ll lim){  if(lim < MAXN) return pcnt[lim];    ll m3 = 1, m2 = 1; while(m3*m3*m3<=lim) m3++; while(m2*m2<=lim) m2++;  m3--;  m2--;  ll y = m3;  ll n = prime_count(y);  ll p2 = 0;  for(ll p=y+1; p<=m2; p++)  {  if(isp[p]){  p2 += prime_count(lim / p) - prime_count(p) + 1;  }      }  ll ph = phi(lim, n);  ll res = ph + n - 1 - p2;  //cout<<lim<<" y "<<y<<" n "<<n<<" p2 "<<p2<<" phi "<<ph<<endl;  return res;}int main(){  init();  while(~scanf("%I64d",&N))  {  ll ans = prime_count(N);  printf("%I64d\n",ans);  }  return 0;}


2 2
原创粉丝点击