当前位置:网站首页>取某一区间中素数的个数--洛谷P1865 A % B Problem
取某一区间中素数的个数--洛谷P1865 A % B Problem
2022-08-03 05:14:00 【程序的搬运工Hunter】
这道题目事洛谷上的一道数论的题目,难度是普及/提高-
题目链接:A % B Problem - 洛谷
这题的内容和题目一点关系都没有,我看到这个题目开始还以为是一道乘法逆元,结果是我想多了
这道题用到了前缀和与素数筛的结合,在素数筛进行筛选的时间同时使用前缀和进行标记。
P1865 A % B Problem
题目背景
题目名称是吸引你点进来的。
实际上该题还是很水的。
题目描述
给定 l, r求区间 [l, r] 内质数的个数。
输入格式
第一行有两个整数,分别代表询问次数 n 和 给定区间的右端点最大值 m。
接下来 n 行,每行两个整数 l, r代表一次查询。
输出格式
对于每次查询输出一行,若 l, r \in [1, m]l,r∈[1,m],则输出区间质数个数,否则输出 Crossing the line
。
输入:
2 5
1 3
2 6
输出:
2
Crossing the line
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 1e6+10;
int a[N];//前缀和进行计数的
bool vis[N];//标记该数有没有被筛过
int n,m;
void shai()
{
a[1] = 0;
vis[1] = 1;
for(int i = 2;i <= n;i++){
if(!vis[i]){//这个数没有被筛过,说明是素数
a[i] = a[i-1]+1;//素数计数个数加一
for(int j = i*2;j <= n;j=j+i){//将该数衍生出的合数进行标记(详情请学习素数筛)
vis[j] = 1;
}
}
else{
a[i] = a[i-1];//这一个数已经被筛掉了,则直接继承前面的素数个数
}
}
}
int main()
{
cin >> m >> n;//输入访问的次数个最大上限
shai();
for(int i = 0;i < m;i++){
int l,r;
cin >> l >>r;
if(l < 1 || r > n)
cout << "Crossing the line" << endl;
else
cout << a[r]-a[l-1] << endl;
}
}