洛谷P1835 素数密度

题目描述:

给定区间 [l.r] ,求出区间内质数的个数

 

数据范围:

1<=l<=r<=1e9

r-l<=1e6

 

思路:

明显是一个筛选质数的问题,由于右端点小于1e9,考虑用线性筛先筛选出sqrt(1e9)的所有素数存放在数组prime中,再遍历从l到r之间的数,设当前点为i,对小于sqrt(i)得所有prime里的数进行枚举,如果有prime满足i mod prime ==0,就可以判断 i 为合数,令 cnt++,遍历后就得到 l 到 r 之间的所有合数,用 r-l+1 减去合数个数cnt就是素数个数,输出答案

 

代码实现:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ll long long

using namespace std;

int const N=50000;
bool isprime[N];
int prime[N];

inline int get()
{
    char c;
    int sign=1;
    while((c=getchar())<'0'||c>'9')
    {
        if(c=='-')
        {
            sign=-1;
        }
    }
    int res=c-'0';
    while((c=getchar())>='0'&&c<='9')
    {
        res=res*10+c-'0';
    }
    return res*sign;
}

int main()
{
    int total=0;
    isprime[0]=1,isprime[1]=1;
    for(int i=2;i<=50000;i++)
    {
        if(isprime[i]==0) prime[++total]=i;
        for(int j=1;j<=total&&i*prime[j]<=50000;j++)
        {
            isprime[i*prime[j]]=1;
            if(!(i%prime[j])) break;
        }
    }
    ll l,r;
    ll cnt=0;
    l=get();
    r=get();
    int j;
    for(int i=l;i<=r;i++)
    {
        int k=sqrt(i);
        j=1;
        while(prime[j]<=k)
        {
            if(i%prime[j]==0)
            {
                cnt++;
                break;
            }            
            j++;
        }
    }
    if(l==1) cnt++;//特判 1 
    cout<<r-l+1-cnt;
    return 0;
}

 

https://www.luogu.com.cn/problem/P1835

再见,祝你好运!

 

 

 
posted @ 2022-06-16 17:13  你的小垃圾  阅读(100)  评论(0编辑  收藏  举报