洛谷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 @   你的小垃圾  阅读(136)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示