传送门P1865https://www.luogu.com.cn/problem/P1865
Atcoder大多了的我一看到这个题目就以为是道省选难度的题,点进去一看:
直接给我吓傻,整不会了。
不开玩笑了,直接入题
这是一道素数筛+前缀和的题
第一步:思考
简单地思考一下后,你会惊奇发现:
设区间 [1,i] 的素数个数为 pre[i],则区间[l,r]的素数个数为pre[r] - pre[l - 1],
做到这里,题目已经解决了一半了
第二步:将问题逐个击破
第一个问题:咋么求sum[i]呢?
这和前缀和有点像,
就是当i为素数时,pre[i] = pre[i - 1] + 1;
否则,pre[i] = pre[i - 1]
就是这样:
for(int i = 1 ; i <= n ; i ++){
if (prime[i]) pre[i] = pre[i - 1] + 1; // prime[i]表示如果i是否为素数,是为true,否则为false
else pre[i] = pre[i - 1];
// cout << i << " " << pre[i] << endl;
}
第二个问题:那咋么求素数呢?
我们知道,有普通的方法,的,但是会超时,因为你每次都要验证一次,就是
的
我这里的n是题目中的m,最大值为1e6。
所以我们要用更快捷,效率更高的方式,就是欧拉筛。
模版:
for(int i = 2; i <= n; i++) prime[i] = true;
for(int i = 2 ; i <= n ; i++){
if (prime[i]){ lst[ ++ lst[0]] = i;}
for(int j = 1 ; j <= lst[0] ; j ++) {
if (i * lst[j] > n) break;
prime[i * lst[j]] = false ;
if (i % lst[j] == 0) break;
}
}
所以,总代码为:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 1048586
#define M 5005
#define N 500005
#define lowbit(x) ((x)&(-(x)))
#define mod 998244353
#define all(s) s.begin(),s.end()
#define Mn(a,b,c) min(a,min(b,c))
#define Mx(a,b,c) max(a,max(b,c))
#define sq(x) ((x) * (x))
#define cub(x) ((x) * (x) * (x))
#define all(s) s.begin(),s.end()
#define e9 1000000000
#define int long long
#define endl "\n"
int yes(int dx){cout << "Yes" << endl;return 0;}
int no(int dx){cout << "No" << endl;return 0;}
string s;
bool prime[MAXN];
int lst[MAXN] ,pre[MAXN];
signed main(){
int n,m,k;
// init();
cin >> m >> n;
for(int i = 2; i <= n; i++) prime[i] = true;
for(int i = 2 ; i <= n ; i++){
if (prime[i]){ lst[ ++ lst[0]] = i;}
for(int j = 1 ; j <= lst[0] ; j ++) {
if (i * lst[j] > n) break;
prime[i * lst[j]] = false ;
if (i % lst[j] == 0) break;
}
}
// 素数筛
for(int i = 1 ; i <= n ; i ++){
if (prime[i]) pre[i] = pre[i - 1] + 1;
else pre[i] = pre[i - 1];
// cout << i << " " << pre[i] << endl;
}
//前缀和
for(int i = 1 ; i <= m ;i ++) {
int l , r;
cin >> l >> r;
if (l < 1 || r > n) cout << "Crossing the line" << endl;
else cout << pre[r] - pre[l - 1] << endl;
}
return 0;
}
所有的问题都解决了,我的任务也完成了