您的位置:首页 > 其它

【codevs3223】素数密度 埃氏筛法

2015-10-29 08:09 176 查看

题目描述 Description

给定区间[L, R](L <= R <= 2147483647,R-L <= 1000000),请计算区间中素数的个数。

输入描述 Input Description

两个数L和R

输出描述 Output Description

一行,区间中素数的个数

样例输入 Sample Input

[code]2 11


样例输出 Sample Output

[code]5


数据范围及提示 Data Size & Hint

详见试题

老题,今天翻出来了…

[a,b]的素数,只需要

[2,b√][2,\sqrt{b}]

的素数表即可。这样我们可以筛出这些素数,然后用这些素数筛[a,b]。

注意,
j=max(2ll,(l+i-1)/i)*i
的意思:

(l+i-1)/i
表示大于等于a的i的倍数的最小值。

2则是普遍的i的倍数的最小值,一定不能小于2。

再乘i,j就可以枚举[a,b]之间的合数了。

代码:

[code]#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int SIZE=1000010;
bool vis[SIZE];
bool pri[SIZE];
typedef long long LL;
int main()
{
    LL l,r;
    scanf("%lld%lld",&l,&r);

    for(LL i=2;i<=sqrt(r);i++)
    {
        if(!vis[i])
        {
            for(LL j=i*i;j<=sqrt(r);j+=i) vis[j]=1;

            for(LL j=max(2ll,(l+i-1)/i)*i;j<=r;j+=i) pri[j-l]=1;  
        }
    }
    int ans=0;
    for(int i=0;i<=r-l;i++) if(!pri[i]) ans++;
    printf("%d",ans);

    return 0;
}
/*
g++ codevs3223.cpp -o codevs3223.exe -Wall
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: