洛谷 P1835 素数密度

 

https://www.luogu.org/problemnew/show/P1835

 

对于40%,对每个数进行最大$O(\sqrt n)$的判断,因为n比较大所以超时。

想到线性筛,然而我们并不能筛到2e9,时间空间都不允许因为2e9素因子最大也到不了50000,我们预处理出2-50000以内的素数,然后对于每一个数,一个一个的出素因子,进行判断,这里放一下代码。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#define LL long long

using namespace std;
int l,r,cnt;
bool p[50006],vis[50006];
int a[50006],tot;
void prepare()
{
    for(int i=2;i<=50000;i++)
    {
        if(!p[i])a[++tot]=i;
        for(int j=1;j<=tot&&i*a[j]<=50000;j++)
        {
            p[a[j]*i]=1;
            if(i%a[j]==0)break;
        }
    }
}
int main()
{
    prepare();
    
    scanf("%d%d",&l,&r);
    for(int i=l;i<=r;i++)
    {
        bool f=0;
        int k=sqrt(i);
        for(int j=1;a[j]<=k;j++)
        {
            if(i%a[j]==0)
            {
                f=1;
                break;
            }
        }
        if(!f)cnt++;
    }
    printf("%d",cnt);
}
View Code

似乎并不是很理想啊,只有90分,那么,我们利用线性筛的思想(用小的素因子来筛大的)。

我们对于每一个质数,最区间内这个数的倍数打上标记,最后统计个数。

然而,你可能会说数据组开不到那么大。

这里我们数组不用开的太大,假设数组为a,那么将l作为数组的第一个元素,这样的话数组最大1000000.

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <map>
using namespace std;
long long l,r,cnt,ans;
bool p[50006];
int a[50006],tot;
bool vis[1000006];
void prepare()
{
    for(int i=2;i<=50000;i++)
    {
        if(!p[i])a[++tot]=i;
        for(int j=1;j<=tot&&i*a[j]<=50000;j++)
        {
            p[a[j]*i]=1;
            if(i%a[j]==0)break;
        }
    }
}
int main()
{
    prepare();
    scanf("%lld%lld",&l,&r);
    int c=sqrt(r);
    for(int i=1;i<=tot&&a[i]<=c;i++)
    {
        for(long long j=(l/a[i])*a[i];j<=r;j+=a[i])
        {
            if(j>=l&&j!=a[i])vis[j-l]=1;
        }
    }
    for(int i=0;i<=r-l;i++)
        if(!vis[i])ans++;
    printf("%lld",ans);
}

 

posted @ 2018-10-02 11:28  Manjusaka丶梦寒  阅读(269)  评论(0编辑  收藏  举报