Light oj 1197

题目链接:http://lightoj.com/volume_showproblem.php?problem=1197

给你a和b求a到b之间的素数个数。

先在小区间素数筛,大区间就用类似素数筛的想法,把a到b之间不是素数的标记出来。因为b-a最多1e5的大小,所以每组数据的时间复杂度最多就o(1e5 log1e5)。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 const int MAXN = 2e5 + 5;
 6 typedef long long LL;
 7 bool prime[MAXN] , vis[MAXN];
 8 LL p[MAXN / 5];
 9 
10 void init() {
11     prime[1] = true;
12     int cont = 0;
13     for(int i = 2 ; i < MAXN ; i++) {
14         if(!prime[i]) {
15             p[++cont] = i;
16             for(int j = i * 2 ; j < MAXN ; j += i) 
17                 prime[j] = true;
18         }
19     }
20 }
21 
22 int main()
23 {
24     init();
25     int t , a , b;
26     scanf("%d" , &t);
27     for(int ca = 1 ; ca <= t ; ca++) {
28         scanf("%d %d" , &a , &b);
29         int res = 0;
30         if(b < MAXN) {
31             for(int i = a ; i <= b ; i++) {
32                 if(!prime[i])
33                     res++;
34             }
35         }
36         else {
37             memset(vis , false , sizeof(vis));
38             for(int i = 1 ; p[i]*p[i] <= b ; i++) {
39                 LL k = a / p[i];
40                 if(k*p[i] < a)
41                     k++;
42                 if(k == 1) //此时a%p[i]==0 && a/p[i]==1,说明a刚好是一个素数
43                     k++;
44                 while(k * p[i] <= b) { //筛选a~b中不是素数的
45                     vis[k*p[i] - a] = true;
46                     k++;
47                 }
48             }
49             for(int i = a ; i <= b ; i++) {
50                 if(!vis[i - a])
51                     res++;
52             }
53         }
54         printf("Case %d: %d
" , ca , res);
55     }    
56 }
原文地址:https://www.cnblogs.com/Recoder/p/5346368.html