abc084d <素数筛 前缀和>

发布时间 2023-07-15 10:03:50作者: O2iginal

题目

D - 2017-like Number

思路

  • 筛出数据范围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;
}