P1865 A % B Problem
题目背景
题目名称是吸引你点进来的
实际上该题还是很水的
题目描述
区间质数个数
输入输出格式
输入格式:
一行两个整数 询问次数n,范围m
接下来n行,每行两个整数 l,r 表示区间
输出格式:
对于每次询问输出个数 t,如l或r∉[1,m]输出 Crossing the line
Solution
所以就复习一下质数筛咯
数据范围不大可以考虑筛法
先线性筛过去, 然后得到一个 (vis) 数组表示是否为质数
在弄一个前缀和就可以 (O(1)) 查询区间质数个数了
Code
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
#include<climits>
typedef long long LL;
using namespace std;
int RD(){
int out = 0,flag = 1;char c = getchar();
while(c < '0' || c >'9'){if(c == '-')flag = -1;c = getchar();}
while(c >= '0' && c <= '9'){out = out * 10 + c - '0';c = getchar();}
return flag * out;
}
const int maxn = 1000019;
int T, m;
bool vis[maxn];
int sum[maxn];
int prime[maxn], nump;
void get_prime(int n){
for(int i = 2;i <= n;i++){
if(!vis[i])prime[++nump] = i;
for(int j = 1;j <= nump && prime[j] * i <= n;j++){
vis[prime[j] * i] = 1;
if(i % prime[j] == 0)break;
}
}
}
int main(){
T = RD();m = RD();
get_prime(m);
vis[1] = 1;
for(int i = 1;i <= m;i++)sum[i] = sum[i - 1] + (vis[i] ^ 1);
while(T--){
int l = RD(), r = RD();
if(l < 1 || r > m){puts("Crossing the line");continue;}
printf("%d
", sum[r] - sum[l - 1]);
}
return 0;
}