嘘~ 正在从服务器偷取页面 . . .

洛谷P1835 素数密度 题解


洛谷P1835 素数密度 题解

题目链接:P1835 素数密度

题意

给定 \(L,R\),请计算区间 \([L,R]\) 中素数的个数。

输入格式

第一行,两个正整数 \(L\)\(R\)

输出格式

一行,一个整数,表示区间中素数的个数。

数据范围

\(1\leq L\leq R < 2^{31}\)\(R-L\leq 10^6\)

z注意到 \(\sqrt{R}\) 只有约 \(V=50000\) 的数量级

我们可以预处理出小于 \(50000\) 的质数,然后用这些质数暴力埃氏筛。

时间复杂度 \(\mathcal{O}\left(\frac{V}{\ln V} \log (R-L)\right)\)

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
const int _ = 50000;
void up(int &x,int y) { x < y ? x = y : 0; }
void down(int &x,int y) { x > y ? x = y : 0; }
#define N ((int)(1e6 + 15))

char ck[N], vis[N]; int pcnt, pri[N];
void init()
{
    for(int i = 2; i <= _; i++)
    {
        if(!ck[i]) pri[++pcnt] = i;
        for(int j = 1; j <= pcnt && pri[j] * i <= _; j++) {
            ck[pri[j] * i] = true; if(i % pri[j]) break;
        }
    }
}
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    // freopen("check.in","r",stdin);
    // freopen("check.out","w",stdout);
    int l, r; cin >> l >> r; init(); if(l == 1) l = 2;
    for(int i = 1; i <= pcnt; i++)
    {
        int &p = pri[i], o = max((l + p - 1) / p * p, 2 * p);
        for(int j = o; j <= r; j += p) vis[j - l + 1] = true;
    }
    int res = 0;
    for(int i = l; i <= r; i++) res += (!vis[i - l + 1]);
    cout << res << '\n';
    return 0;
}

参考文献

[1] https://www.luogu.com.cn/article/arizrqsd


题外话

都说了早上脑子不好使了啦。


文章作者: q779
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 q779 !
评论
  目录