1. 程式人生 > >洛谷 P1835 素數密度

洛谷 P1835 素數密度

pri lose spl 密度 hide fin main 預處理 vector

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);
}

洛谷 P1835 素數密度