很明显本题数据极大如果不预处理,就算用欧拉筛也不能过
这道题的策略就是将所有的职数筛出,然后遍历一波,通过前缀和的方式,计算出每个数包括此数以及之前有多少个素数,最后求区间数直接相减就好
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#define maxn 1000005
using namespace std;
int n,m;
int a,b,book[maxn];
int ans=0;
int f[maxn];
int s[maxn];
void seive(int y)
{
int cnt=0;
book[1]=1;
for(int i=2;i<=y;i++)
{
if(!book[i])
{
cnt++;
s[cnt]=i;
}
for(int j=1;i*s[j]<=y&&j<=cnt;j++)
{
book[i*s[j]]=1;
if(i%s[j]==0) break;
}
}
}
void find()//求前缀和
{
for(int i=2;i<=m;i++)
{
if(!book[i])
f[i]=f[i-1]+1;
else
f[i]=f[i-1];
}
}
int main()
{
scanf("%d %d",&n,&m);
seive(m);
find();
while(n--)
{
scanf("%d %d",&a,&b);
ans=0;
if(a<1||a>m||b<1||b>m)
{
cout<<"Crossing the line"<<endl;
continue;
}
else
{
if(!book[a])
cout<<f[b]-f[a]+1<<endl;
//如果a是素数,那么就会多减掉a这个素数
//而题目中要求的是闭区间,所以需要加上
else
cout<<f[b]-f[a]<<endl;
}
}
return 0;
}