题意:
求区间[a,b]中的素数的个数。
思路:
直接枚举0—sqrt(b)这个范围的素数,将[a,b]中的倍数去掉。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
using namespace std;
typedef long long ll;
const int maxn = 100005;
int prime[maxn];
bool isprime[maxn];
bool flag[maxn];
void getprime(){
memset(isprime, 0, sizeof(isprime));
int h = 0;
for(int i = 2;i < maxn;i++){
if(!isprime[i]){
prime[h++] = i;
for(int j = i+i;j < maxn;j += i)
isprime[j] = 1;
}
}
// for(int i = 0;i < 100;i++)
// printf("%d ",prime[i]);
}
int main(){
getprime();
int t;
scanf("%d",&t);
ll a,b;
for(int cas = 1;cas <= t;cas++){
scanf("%lld%lld",&a,&b);
memset(flag, 0, sizeof(flag));
if(a<2) a = 2;//特别要注意当a == 1 的时候起点要进行调整
for(int i = 0;(ll)prime[i]*prime[i] <= b;i++){
//调整枚举的起点,找到第一个在[a,b]区间内prime[i]的倍数
ll j = (ll)prime[i]*(a/prime[i]);
if(j < a) j += prime[i];
if(j == prime[i]) j = prime[i]+prime[i];//j比较小的时候
for( ;j <= b;j += prime[i])
flag[j-a] = 1;
}
int ans = 0;
for(int i = 0;i <= b-a;i++)
if(!flag[i])
ans++;
printf("Case %d: %d\n",cas,ans);
}
return 0;
}