數論_埃氏篩法(求區間內多少素數)

埃拉託斯特尼(公元前276—公元前194)ios


埃拉託斯特尼是古希臘著名的數學家、地理學家、天文學家。他先在亞歷山大港學習,後又轉至雅典。公元前236年,托勒密三世指定他爲亞歷山大圖書館的圖書管理員和館長。他跟阿基米德是好朋友。埃拉託斯特尼的主要貢獻包括:算法

埃拉託斯特尼篩法:尋找素數的方法。學習

地理常數測量:日地間距的測量(如今稱一個這樣的距離爲一個天文單位)、地月間距的測量、測量赤道與黃道之間的偏角、地球半徑測量等。spa

精確地圖繪製:當時只有托勒密等級的人物能繪出同等級的地圖。code

算法數學原理:
埃拉託斯特尼篩法是快速篩選素數的算法,在處理大量整數是不是素數時有較高的效率。blog

例:篩選小於n的整數並記錄結果。數學

解:計算sqrt(n),∵對於任意的z<n,若z爲合數,不妨設z=a*b,則必有min(a,b)<sqrt(n)string

∴全部小於n的合數都可被小於sqrt(n)的整數整除it

從2開始,依次去除小於n的整數中能被其整除的數,最後剩下的就是素數io

int prime[maxn];
bool is_prime[maxn];//is_prime[i]是true表示i是素數
//返回n之內素數的個數
int sieve(int n)
{
    int p=0;
    for(int i=0;i<=n;i++) is_prime[i]=true;
    is_prime[0]=is_prime[1]=false;
    for(int i=2;i<=n;i++){
        if(is_prime[i]){
            prime[p++]=i;
            for(int j=2*i;j<=n;j+=i) is_prime[j]=false;
        }
    }
    return p;
}

  例題:洛谷 P1865  ,

codevs3223 素數密度

[a,b]的素數,只須要

[2,b√]
的素數表便可。這樣咱們能夠篩出這些素數,而後用這些素數篩[a,b]。

注意,j=max(2ll,(l+i-1)/i)*i的意思:

(l+i-1)/i表示大於等於a的i的倍數的最小值。
2則是廣泛的i的倍數的最小值,必定不能小於2。
再乘i,j就能夠枚舉[a,b]之間的合數了。

 

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int SIZE=1000010;
bool vis[SIZE];
bool pri[SIZE];
typedef long long LL;
int main()
{
    LL l,r;
    scanf("%lld%lld",&l,&r);

    for(LL i=2;i<=sqrt(r);i++)
    {
        if(!vis[i])
        {
            for(LL j=i*i;j<=sqrt(r);j+=i) vis[j]=1;

            for(LL j=max(2ll,(l+i-1)/i)*i;j<=r;j+=i) pri[j-l]=1;  
        }
    }
    int ans=0;
    for(int i=0;i<=r-l;i++) if(!pri[i]) ans++;
    printf("%d",ans);

    return 0;
}
相關文章
相關標籤/搜索