https://www.luogu.com.cn/problem/P1865
原理竟然比较简单:
1.如果一个数字是素数,那就把它的N倍都标成不是素数 并且当时素数的个数要+1
2.如果一个数字已经标记了,那么它就不是素数,当前的素数个数和前面的相同
package info.frady.luogu;
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class P1865 {
static int[] res =new int [1000001];
static boolean[] vis=new boolean[1000001];
public static void main(String[] args) throws Exception{
BufferedReader reader =new BufferedReader(new InputStreamReader(System.in));
//int N=Integer.parseInt(reader.readLine());
//String str=reader.readLine();
String str[]=reader.readLine().split(" ");
int N=Integer.parseInt(str[0]);//询问的次数
int M=Integer.parseInt(str[1]);//右侧最大的区间
shai(M);
for (int i = 0; i < N; i++) {
str=reader.readLine().split(" ");
int l=Integer.parseInt(str[0]);
int r=Integer.parseInt(str[1]);
if(l>=1 && l<=M && r>=1 && r<=M){
System.out.println(res[r]-res[l-1]);
}else{
System.out.println("Crossing the line");
}
}
reader.close();
}
public static void shai(int n)
{
res[1]=0;//到1这个位置,质数的个数为0
vis[1]=true;
for(int i=2;i<=n;i++)
{
if(vis[i]==false) //这个数字没有被访问过,那它就是一个质数,在筛里进行前缀和
{
res[i]=res[i-1]+1;//前缀和计算
for(int j=i+i;j<=n;j=j+i)
{
vis[j]=true;//标记操作
}
}
else res[i]=res[i-1];//前缀和转移,质数的个数没有发生变化
}
}
}