ACM素數打表(模版)

2021-08-17 18:01:28 字數 1394 閱讀 8558

第一次寫部落格。

今天學了兩個很簡單的定理,老是忘記細看,今天可算看了下。

其中乙個是

素數打表的優化

首先先理解了簡單的埃篩法;

埃篩法就是把表中全部數為素數的倍數乙個個篩除,最後只有素數留在表中。

#include#includeusing namespace std;

#define maxn 100000

int check[maxn]=;

int prime[maxn]=;

int main()

} for(int i=0;i時間複雜度為o(n loglog n);

接下來是更為優化的尤拉線性篩法(時間複雜度為o(n))

/*求小於等於n的素數的個數*/

#include#includeusing namespace std;

int main()

{ int n, cnt = 0;

int prime[100001];//存素數

bool vis[100001];//保證不做素數的倍數

scanf("%d", &n);

memset(vis, false, sizeof(vis));//初始化

memset(prime, 0, sizeof(prime));

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

{if(!vis[i])//不是目前找到的素數的倍數

prime[cnt++] = i;//找到素數~

for(int j = 0; jif(i % prime[j] == 0) break;←_←這一步比較難理解

解釋:首先,任何合數都能表示成多個素數的積。所以,

任何的合數肯定有乙個最小質因子。我們通過這個最小質因子就可以判斷什麼時候不用繼續篩下去了。

當i是prime[j]的整數倍時(i % prime[j] == 0),i*prime[j+1]肯定被篩過,跳出迴圈。

因為i可以看做prime[j]*某個數x, i*prime[j+1]就可以看做 prime[j]*x*prime[j+1] 。而 prime[j] 必定小於 prime[j+1],

所以 i*prime[j+1] 這個合數已經被x*prime[j](prime[j]是這個合數的最小質因子)篩掉,就不用再做了

也就是:

i=prime[j]*x;

合數=i*prime[j+1]=i*prime[j]*x;        //prime[j]是合數的最小質因子!

同時我們可以發現在滿足程式裡的兩個條件的時候,prime[j]必定是prime[j]*i的最小質因子。這個性質在某些題裡可以用到。

/*參考了

ACM 素數線性篩法(素數打表)

題目 include include int prime 700000 bool check 10000000 int num 1 int judge int y int j 0 while p j 1 j j i 0 while i j i j return1 int main int j 1 f...

美素數 素數打表

description 小明對數的研究比較熱愛,一談到數,腦子裡就湧現出好多數的問題,今天,小明想考考你對素數的認識。問題是這樣的 乙個十進位制數,如果是素數,而且它的各位數字和也是素數,則稱之為 美素數 如29,本身是素數,而且2 9 11也是素數,所以它是美素數。給定乙個區間,你能計算出這個區間...

高效素數打表

大家所知的素數打表時間複雜度幾乎都是n2。就是這種 void init prime j 0 for i 2 i 1000002 i if prime i prime j i 在網上搜到了另一種方法,效率提高了不少。巧妙之處還在研究中,等理解差不多就仔細分析一下。下面是 大家可以發表一下自己的看法,交...