0023:素数密度(洛谷P1835)

题目传送门:https://www.luogu.com.cn/problem/P1835

数据范围最大有20亿,用普通质数筛10000%超时(就是不超时数组也开不了那么大)

由于r-l不超过10^6,所以我们可以先筛出较小的质数,然后用这些质数去筛那个区间里的质数

另外由于数组开不了20亿,但可以开10^6,所以可以吧这些质数压缩在1开始的数组里。

代码:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e6+1;
ll l,r;
int prime[maxn],cnt,ans;
bool vis[maxn],vis2[maxn];
void Q(){//普通质数筛,筛50000以内的质数 
    for(int i=2;i<=50000;i++){
        if(vis[i]==0){
            prime[++cnt]=i;
            for(int j=2;j<=50000/i;j++){
                vis[i*j]=1;    
            }
        }
    }
}
int main(){
    cin>>l>>r;
    if(l==1){//1的特判 
        l=2;
    }
    Q();
    for(int i=1;i<=cnt;i++){//枚举50000以内的这些质数 
        ll p=prime[i],start;
        if((l+p-1)/p>2){//判断如果l很小的情况 
            start=(l+p-1)/p*p;//更新初始值
        }else{
            start=2*p;
        }
        for(ll j=start;j<=r;j+=p){
            vis2[j-l+1]=1;//标记区间内的质数 
        }
    }
    for(ll i=1;i<=r-l+1;i++){
        if(vis2[i]==0){
            ans++;//计数 
        }
    }
    cout<<ans;
}

 

posted @ 2022-08-10 09:46  uf0_金币灰黄^w.h  阅读(77)  评论(0)    收藏  举报