Help Hanzo
题解:因为区间太大,所以我们需要考虑再仔细看一下题,求的是 [ a , b ] [a,b] [a,b]区间内的素数,并且 b − a ≤ 100000 b - a ≤ 100000 b−a≤100000,因此我们可以借用素数筛的思想,将 [ a , b ] [a,b] [a,b]区间内的合数筛去。具体做法就是先找到区间[a,b]内的第一个合数
int t = prime[i] * ceil(1.0 * a / prime[i]);
(注意可能这个数是素数,需要判断一下)然后开始素数筛,最后枚举一下多少个素数即可。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 100100;
int prime[N];
bool vis[N];
int init()
{
int k = 0;
for(int i = 2; i < N; ++i) {
if(vis[i] == 0)
prime[k++] = i;
for(int j = 2; j * i < N; ++j) {
if(vis[i * j] == 0)
vis[i * j] = 1;
}
}
return k;
}
bool book[N];
int main() {
#ifndef ONLINE_JUDGE
freopen("input.in", "r", stdin);
#endif
int T, a, b, k = init(), w = 1;
cin >> T;
while (T--) {
cin >> a >> b;
memset(book, 0, sizeof book);
for (int i = 0; i < k && prime[i] <= sqrt(b); ++i) {
int t = prime[i] * ceil(1.0 * a / prime[i]);
if (t % prime[i] == 0 && t != prime[i])
book[t - a] = 1;
for (int j = 1; j * prime[i] <= b - a; ++j) {
int tmp = j * prime[i] - a + t;
if (book[tmp] == 0)
book[tmp] = 1;
}
}
int cnt = 0;
for (int i = a; i <= b; ++i)
if (book[i - a] == 0) {
cnt++;
}
if (a == 1) cnt--;
cout << "Case " << w++ << ": " << cnt << endl;
}
return 0;
}