标签:set 要求 max include i++ pre using out 个数
小 tan 的老师揣谙戈给同学们布置了一道题,要求统计给定区间内素数的个数。“这不是很简单吗?”小 tan 忍不住说。揣谙戈冷笑 一下说:“等你们看到题目就知道了。”便转身离去。
果然,小 tan 被那极大的区间吓怕了,现在是你拯救她的时候。
输入文件名为 pcount.in
。
输入一行两个正整数 \(a\) 和 \(b\),表示给定区间为 \([a,b]\)。
输出文件名为 pcount.out
。 输出一个整数,表示区间内素数数量。
pcount.in
1 17
pcount.out
7
对于 \(30\%\) 的数据,有 \(n<m\le1000\);
对于 \(60\%\) 的数据,有 \(n<m\le1000000\);
对于 \(100\%\) 的数据,有 \(n<m<2^{31}\),\(m-n\le1000000\)。
对于每个合数 \(c\),必然存在一个 \(p\) 使得 \(p|c\) 且 \(p\le\sqrt{c}\).
想要筛 \([L,R]\) 中的素数,瓶颈在于 \(R\). 有了这个结论,可以只筛 \([1,\sqrt{R}]\) 的素数,并用这些素数筛 \([L,R]\) 中的数。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MAX_SQRT 66000
#define MAXN 1000000
#define MAXL 1000050
ll a, b, ps[MAXN];
bool isp[MAX_SQRT], ispr[MAXL];
int pt = 0;
void filt() {
isp[1] = false;
for (ll i = 2; i * i <= b; i++)
isp[i] = true;
for (ll i = 1; i * i <= b; i++) {
// cout << i << endl;
if (!isp[i]) continue;
// cout << i << endl;
ps[pt++] = i;
for (ll j = i * i; j * j <= b; j += i)
isp[j] = false;
}
}
void isprset(ll i, bool v) {
ispr[i - a] = v;
}
bool isprget(ll i) {
return ispr[i - a];
}
int main() {
// freopen("pcount.in", "r", stdin);
// freopen("pcount.out", "w", stdout);
cin >> a >> b;
filt();
// cout << "here" << endl;
// for (int i = 0; i < pt; i++) cout << ps[i] << " ";
// cout << endl;
for (ll i = a; i <= b; i++)
isprset(i, true);
for (int i = 0; i < pt; i++) {
int p = ps[i];
for (ll j = max(a / p * p, 2ll * p); j <= b; j += p) {
isprset(j, false);
}
}
int ans = 0;
for (ll i = max(a, 2ll); i <= b; i++)
if (isprget(i)) {
ans++;
// cout << i << endl;
}
cout << ans << endl;
return 0;
}
标签:set 要求 max include i++ pre using out 个数
原文地址:https://www.cnblogs.com/lrw04/p/11852948.html