题目
思路
- 筛出数据范围
1e5
范围内的素数 - 检查每个素数是否为 2017-like
- 对
1~1e5
内的2017-like求前缀和, 回答询问
总结
- 如果数据范围允许, 进行预处理, 查表回答询问
代码
Code
// https://atcoder.jp/contests/abc084/tasks/abc084_d
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
using LL = long long;
const int N = 1e5 + 10;
bool st[N];
int cnts[N];
int primes[N], cnt;
// 埃氏筛
void get_primes(int n)
{
for (int i = 2; i <= n; i ++)
{
if (!st[i]) primes[cnt ++] = i;
for (int j = 0; primes[j] <= n / i; j ++)
{
st[i * primes[j]] = true;
if (i % primes[j] == 0) break;
}
}
}
void solv()
{
get_primes(N-1);
for (int i = 1; i < cnt; i ++) // 从第二个素数开始, 因为要求n为奇数, 不包含2
{
int n = primes[i];
int t = (n + 1) / 2;
if (!st[t]) cnts[n] = 1;
}
for (int i = 1; i < N; i ++) cnts[i] += cnts[i-1]; // 前缀和
int q, l, r;
cin >> q;
while (q --)
{
cin >> l >> r;
cout << cnts[r] - cnts[l-1] << endl;
}
}
int main()
{
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
int T = 1;
// cin >> T;
while (T --)
{
solv();
}
return 0;
}