關於埃式篩法的極限優化

2022-05-01 18:03:09 字數 804 閱讀 4922

摘自

關於素數的普通篩法想必大家都清楚。使用乙個陣列vis[n],從2遍歷到n-1,每次碰到素數就把它的倍數剔除。這裡有三種手段可以大大降低埃式篩法的時間複雜度:

先發埃式篩法模板,假設初始化vis所有成員為0,0代表是素數,1代表不是素數:

1

for(int i=2;i<=n;i++)6}

7 }

那麼首先會想到乙個問題,乙個合數如果有因數,那麼必定是成對存在,也就是篩子只用判斷其中乙個因數就可以了,比如15=3*5,在3的時候已經把15給篩掉了,何必去迴圈到5呢?於是優化如下,迴圈到根號n即可。

1

for(int i=2;i*i<=n;i++)6}

7 }

接下來是第二重優化。第二層迴圈中不是從j=2i開始,每次增加乙個i,即剔除i的所有倍數嗎?試想一下,6是不是被2篩過了,此時碰到素數3又要篩一遍。而j從2i到i*i,即2倍到i倍的變化,在第一層迴圈中,2~i-1已經把他們的素數倍數篩完,所以結論如下:

第i個數只用篩從 i 乘 i 開始到n的每個數,而不用從 2 乘 i 開始

接下來優化**:

1

for(int i=2;i*i<=n;i++)6}

7 }

第三重優化是乙個很小的改動與優化,在第二重迴圈中,每次增加素數的1倍,但除了2以外素數都是奇數,那麼奇數乘以偶數是偶數,偶數情況早已被2篩完,故每次增加2i倍.

1

for(int i=2;i*i<=n;i++)8}

9 }

埃式篩法 尤拉篩法

埃氏篩法是通過從小到大篩去乙個已知素數的倍數進而實現篩選的。假如我們想篩掉1 100間的所有合數,步驟如下 2是質數,篩掉所有2的倍數 3是質數,篩掉所有3的倍數 4不是質數,跳過 5是質數,篩掉所有5的倍數 6不是質數,跳過 7是質數,篩掉所有7的倍數 8不是質數,跳過 9不是質數,跳過 10不是...

埃式篩法 快速冪運算

應用 對很多整數進行素性測試 要列舉n以內的素數 思路 2 n範圍內的所有整數,依次遍歷。遍歷過程中如果該數是素數則將其的倍數都劃去 可以想象他的倍數一定為非素數 遍歷完成後。就可以列舉n以內的素數了。模板 void sieve int n for int i 2 i n i 依次遍歷 printf...

篩法 尤拉篩和埃式篩(詳細至極)

首先,篩法是一種用來判斷質數的方法,可以刷出乙個質數表,所以也叫刷表法。基本思想 乙個整數的1以上且為整數倍是乙個合數。我們可以從小到大列舉n以內的質數,對其不超過n的倍數進行標記,剩下未標記的數即為質數。基本寫法 for int i 2 i n i 這時,我們會驚奇地發現時間複雜度很高。下面我們開...