区间素数的个数(埃氏筛法的基础上加内容)

给定整数a和b,请问区间[a,b)内有多少个素数?

a< b<=10^12

b-a<=10^6

输入 
22 37 
输出 

输入 
22801763489 2280178297 
输出 
1000

【分析】b以内的合数的最小质因数一定不超过sqrt(b)。如果有sqrt(b)以内的素数表的话,就可以把埃式筛法运用在[a,b)上了。也就是说,先分别做好[2,sqrt(b))的表和[a,b)的表,然后从[2,sqrt(b))的表中筛得素数的同时,也将其倍数从[a,b)的表中划去,最后剩下的就是区间[a,b)内的素数了。

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 typedef long long ll;
 5 const ll MAX_N=100050;
 6 
 7 bool is_prime[MAX_N];
 8 bool is_prime_small[MAX_N+1];
 9 
10 int segment_sieve(ll a, ll b)
11 {
12     int x = 0;
13     for(int i = 0; (ll)i*i < b; i++) is_prime_small[i]=true;
14     for(int i = 0; i < b - a; i++) is_prime[i]=true;
15     
16     for(int i = 2; (ll)i*i < b; i++)
17     {
18         if(is_prime_small[i])
19         {
20             for(int j = 2*i; (ll)j*j < b; j+=i) is_prime_small[j]=false;
21             for(ll j=max(2LL,(a+i-1)/i)*i;j<b;j+=i)
22             {
23                 is_prime[j-a]=false;
24                 x++;
25             } 
26         }
27     }
28     return x;
29 }
30 
31 int main()
32 {
33     ll a,b;
34     cin>>a>>b;
35     segment_sieve(a,b);
36     int cnt=0;
37     for(int j=0; j<b-a; j++)
38     {
39         if(is_prime[j])cnt++;
40     }
41     if(a==1)cnt--;
42     printf("%d\n",cnt);
43 }
View Code

 

posted @ 2018-04-23 22:14  奋斗の小白  阅读(290)  评论(0编辑  收藏  举报