1億以內素數的個數 數論基礎素數篩

2021-10-14 12:18:56 字數 2517 閱讀 1230

一.什麼是素數

長話短說:因數只有1和本身的正整數,(但素數不包含1). 比如 2 ,3,5,7.......

二.如何判斷乙個數是素數

用1中的定理,也就是說,如果某個大於1的正整數與任何小於等於它的正整數的最大公因數都是1,則為素數。

咳咳咳....扯遠了,我們的重心不在這裡,重點在下面:

三.什麼是素數篩

首先,給你乙個區間的正整數,讓你求在這段區間內有哪些素數?這裡,我們就可以用「篩選的方法」篩去不是素數的正整數(也就是合數)剩下的就是素數了,但不同的篩法效率也是不一樣的。

1. 最直接的篩法

獲取1到n以內的所有素數

int prime[200000]=,c=0;  //儲存素數的陣列,陣列裡面素數的個數void getprime(int n)        }        //如果執行了上面**flag還是0,說明i就是素數        if(!flag) prime[++c] = i;    }}
這種方法甚至稱不上是篩,壓根就是暴力列舉。。複雜度o(n*sqrt(n))

2. 埃氏篩

又稱為埃拉託斯特尼篩法,是一種比較古老的篩分,我們直接來看它的篩法原理

準備乙個判斷是否素數的陣列

bool isprime[20000];
初始化:假設 2 - n都是素數。(1不是,我們先排除)

for(int i=2;i<=n;++i)        isprime[i] = true;
**如下:

void getprime(int n)
這是一種比較古老的素數篩選法,時間複雜度o(n*logn)評價:一般題目都可以使用。

3. 尤拉篩(線性篩)

尤拉篩基本上是埃氏篩的優化公升級版,為什麼這麼說?我們來看乙個問題:比如我要篩選 1 - 20以內所有的素數,就以埃氏篩來完成。

尤拉篩(也叫線性篩)。

《1》我們定義乙個儲存素數的陣列

int prime[20000];
《2》我們定義乙個記錄素數陣列內素數個數整型

int c = 0;
《3》我們定義乙個用來判斷某個數是否已經被訪問的陣列

bool isvisit[20000]; //預設都是false
void eulersevie(int n)    }}

(這是當i為素數的情況下)尤拉每次得出素數的時候,再進入迴圈,根據此時素數陣列的個數來篩選掉此時i的倍數,而且這個倍數一定是素數(由prime可以得知)。

(當i不是素數的時候)此時的i一定被標記為true,也就是 i 之前的素數將其標記為true,這樣子就避免了非素數 i 進入第乙個if而被儲存在素數陣列裡面(至於為什麼被標記為true自己筆寫一遍就曉得了,不多說)  。

最後一步有乙個(i % prime【j】==0) 首先此時的 i 不可能為素數,因為素數模其他素數不可能被整除,也就是說,這個i一定是合數。

理解一下最後乙個跳出迴圈,如果prime【j】是i的倍數的時候,也就是說

i = m * prime【j】,  ...................①  

假如沒有這個break條件,則++j,也就是算到了

i * prime【j+1】這裡了    

把①式子帶入下面式子可以知道此時為

m * prime【j】* prime【j+1】

結合尤拉篩的定理,其是根據最小素數因子進行篩選,也就是說prime【j】 是最小素數因子,如果不break的話,可能會出現埃氏篩那種重複操作的無用功,比如:

i = 9 的話,此時prime=2,prime=3,prime=5,prime=7;

本來是當 j=2 的時候跳出迴圈,但是卻沒有,那麼

j = 3  則 9 * 5 = 3 * 3 * 5 ,該統計在 i  = 15 的時候也會統計,也就是當 i = 15 時候,

j = 2 ,prime = 3,也統計了 3 * 15 = 9 *5

明顯,重複統計,所以要及時break;

尤拉篩:時間複雜度o(n),普遍使用的素數篩。

評價:普遍使用

ps:至於陣列定義多大,int還是long long int,完全取決於題目要求  拿下面數論比賽練練手吧:

素數基礎篇 之 素數的個數 czyuan原創

了解了基本的判斷方法後,你是不是有個疑問 我們能判斷素數的個數嗎?總所周知,素數的個數是無限的,且沒有固定的公式 但如果我們只要判斷 a,b 區間 a,b範圍為1到1億 內的素數的個數呢?首先,我們可以想到,如果要求的素數個數區間 a,b 當區間長度比較小 10 6內 我們可以用篩法求出區間內的所有...

C 實現統計100以內所有素數的個數

統計100以內所有素數的個數 素數 prime number 又稱質數,在大於1的自然數中,除了1和它本身以外不再有其他因數的數稱為質數,2是最小的素數。最大範圍內數字 int maxnum 100 所有素數和,初始0 int sum 0 2是最小的素數,for迴圈範圍為2 100 for int ...

埃氏篩法 快速篩選n以內素數的個數

給你乙個數n,請問n以內有多少個素數?n 10e7 一般來說,要是對乙個整數進行素數判斷,首先想到的是寫個函式判斷是否為素數,然後呼叫這個函式,時間複雜度為o n 但是要求n以內的素數就略顯吃力了.要是求n以內的素數個數的話,可以用埃式篩選.預處理一下.先看下面的 1 2 埃式篩法 3 快速篩選素數...