【codevs3223】素数密度 埃氏筛法

来源:互联网 发布:手机淘宝改收货地址 编辑:程序博客网 时间:2024/05/04 01:06

题目描述 Description

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

输入描述 Input Description

两个数L和R

输出描述 Output Description

一行,区间中素数的个数

样例输入 Sample Input

2 11

样例输出 Sample Output

5

数据范围及提示 Data Size & Hint

详见试题


老题,今天翻出来了…

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

[2,b]

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

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

(l+i-1)/i表示大于等于a的i的倍数的最小值。
2则是普遍的i的倍数的最小值,一定不能小于2。
再乘i,j就可以枚举[a,b]之间的合数了。

代码:

#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*/
2 0
原创粉丝点击