RT:
有n个询问,你需要统计L到R范围内,有多少个数是素数。
输入
第一行一个整数n,表示询问个数。
接下来n行,每行两个整数L和R
输出
对于每个询问,输出一个整数,表示这个区间素数的个数。
输入 1
3 1 5 4 10 7 13
输出 1
3 2 3
提示
50%的数据,满足1≤L,R≤5∗10^3,n≤10^3
70%的数据,满足1≤L,R≤5∗10^5,n≤10^3
100%的数据,满足1≤L,R≤5∗10^6,n≤10^5
思路+解答
思路:
-
创建一个长度为n+1的bool数组,初始将所有元素标记为"未访问"或"未筛"(通常用
true
表示未筛选,false
表示已筛选)。 -
从2开始,遍历数组中的每个数字(从2到n):
- 如果当前数字已经被标记为"已筛",则跳过。
- 如果当前数字未被标记为"已筛",则将其标记为"已筛",因为它是素数。
-
在第2步中,如果标记某个数字x为素数,那么将x的所有倍数(2x,3x,4x,...)标记为"已筛选"。这些倍数肯定不是素数,因为它们都能被x整除。
-
重复步骤2和步骤3,直到遍历完所有小于等于n的数字。
-
最后,所有未被标记为"已筛"的数字就是素数。
Q:埃筛是啥?
A:埃氏筛法,简称埃筛。是一种用于预处理小于等于给定数 n 的所有素数的算法。
使用一个bool数组来存储小于等于 n 的数是否为素数,然后逐个遍历这些数,并根据它们是否为素数来更新数组中其他数的状态。
动图(网图!!)
要注意范围!(int,超过int)
下面是本题的详细代码
AC代码
#include <bits/stdc++.h>
using namespace std;
bool vis[100000010];
int n,ans=0;
int main(){
scanf("%d",&n);
vis[0]=vis[1]=1;
for(int i=2;i*i<=n;i++)
{
if(vis[i]!=1)
{
for(int j=i*i;j<=n;j+=i)
{
vis[j]=1;
}
}
}
for(int i=2;i<=n;i++)
{
if(vis[i]==0)
{
ans++;
}
}
printf("%d",ans);
return 0;
}
撒花~