模板 素數篩法

2022-09-06 17:09:12 字數 1743 閱讀 5586

(好-----快------)

素數是什麼就不用介紹了吧。。。先介紹判斷素數的方法

先看樸素演算法

for (i=2;i) 

if (n%i==0) break

;if (i==n) printf(「n is

prime」);

else printf(「n is not prime」);

(真的好樸素。。)

用時o(n)

(肯定不行啊,吃棗藥丸的。。)

怎麼優化呢?

不難發現,如果a是n的約數,那麼n/a也是n的約數

所以就有以下**:

n2=int(sqrt(n)+0.5

);for (i=2;i<=n2;i++) if (n%i==0) break

;if (i>n2) printf(「n is

prime」);

else printf(「n is not prime」);

這個用時o(n^0.5)

一般使用的話這樣其實差不多了。。(其實有乙個更快的只是我不會。。)

進入正題啦!

盡量快的找出1---n之間的所有素數

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

}if(!flag)

cout

<"";

flag=0

; }

其實也不是很樸素啦。。用了上面介紹的優化,但是速度還是很慢

怎麼優化呢?

對於任意數a,a所有的整數倍都是合數

int flag[2333]; int prime[2333]; int

primes;

for (int i=2;i<=n;i++) flag[i]=0

;for (int i=2;i<=n;i++) for (int j=i*i;j<=n;j+=i) flag[j]=1; //

表示j被標記為合數

for (int i=2;i<=n;i++) if (flag[i]==0) prime[primes++]=i;

有了這個想法,還可以繼續優化

對於質數a,a的所有整數倍都是合數

int flag[2333]; int prime[2333]; int

primes;

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

if (flag[i]==0

)

還可以繼續優化嗎?

其實還可以進一步優化,只要每個合數都只被自己能整除的最小的質數標記一次,速度就可以達到線性級別(好快!)

說白了就是每個質數盡可能多的標記合數(也不是很好懂的樣子?)

看**吧:

#includeusing

namespace

std;

int prime[100001

];int f[100001

],primes;

intn;

intmain()

for(int j=0;j//

列舉當前找到的所有素數

}cout

素數個數

for(int i=0;i)

return0;

}

(rp++!)

素數篩法(模板)

質數 在大於1的整數中,如果只包含1和本身這兩個約數,那麼就是素數時間複雜度 o sqrt n static boolean prime int n return true 合數只會被它的最小質因子篩掉 時間複雜度 o n static final int n static int prime ne...

素數篩法 模板

為什麼只遍歷到sqrt n 就夠了?反證法 假設只遍歷2 sqrt n 不能把所有非素數置為false,即遍歷完了2 sqrt n 後,在sqrt n n範圍內仍有乙個非素數k,但isprime k true。證 k在sqrt k 之前一定有乙個素數因子 任何非素數都可以拆成素數的乘積,所以k至少有...

素數篩法(素數篩 線性篩)

求素數的方法在現階段可以總結為三種 這種方法最為簡單但效率太低,經過優化時間複雜度最低是o n sqrt n 輸入乙個n,輸出n以內所有素數 include intprime int n if flag 0 優化 printf d i intmain 素數篩法原理 2是素數,那麼2的所有倍數都是合數...