求有限区间内素数个数

 

[l, r]这段区间中有多少素数

1 l r 10 ^6

 

一个显然的想法是利用for循环枚举[l, r]中的每一个数。然后利用朴素算法O(X)进行判断。

整体复杂度O(NN),不符合要求

#include<iostream>
using namespace std;

int r,l;
int ans;

int main(){

    cin>>r>>l;
    for( int i=r ; i<=l ; ++i ){
        if( n%i!=0 ){
            ans++;
        }
    }
    cout<<ans;
    
    return 0;
}

 

 

仍然考虑枚举判断每个数是否是素数,但我们这次从2开始判断。

考虑对于任意一个数x,不论x是否为素数,都x*2,x*3,x*4...为合数。我们“筛”掉这些必然为合数的数。那么当我们枚举到ii还没有被筛掉,那么i必然为素数。

时间复杂度O(NlogN)

#include<iostream>
using namespace std;

int r,l;
int prime[1e6],c;
bool num[1e6];
int ans;

int main(){
    cin>>r>>l;
    
    for( int i=2 ; i<=l ; ++i ){
        if( !num[i] ) prime[++c]=i;
        if( i>=r && i<=l && !num[i] ) ans++;
        for( int j=1 ; i*prime[j]<=n && j<=c ; ++j ){
            num[ i*prime[j] ] = 1;
            if( i%prime[j]==0 ) break;
        }
    }
    
    cout<<ans;
    
  return 0;
}

 

T次询问,每次询问[lr]中有多少素数

≤ ≤ 10^5≤ ≤ ≤ 10 ^6

我们用ANSL,R来表示[l, r]中有多少素数,发现ANSL,R = ANS1,R - ANS1,L-1,

于是我们可以维护一个素数个数的前缀和Sum[i]表示[1, i]有多少素数,每次询问就输出Sum[r] - Sum[l - 1]即可 

#include<iostream>
using namespace std;
#define    maxn 1000005 

int sum[maxn],vis[maxn];
int t,l,r;

void pre(){
    for( int i=2 ; i<=maxn ; ++i ){
        sum[i]=sum=[i-1];
        if( !vis[i] ) sum[i]++;
        for( int j=i*2 ; j<=maxn ; j+=i ) vis[j]=1;
    }
}

int main(){
    pre();
    
    cin>>t;
    while( t-- ){
        cin>>l>>r;
        cout<<sum[r]-sum[l];
    }
    
    return 0;
}

 

 

 



 

posted @ 2019-04-28 19:42  莫瑞  阅读(703)  评论(0编辑  收藏  举报