题目链接: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 }