篩法 求n以內質數個數

2021-09-10 07:30:30 字數 3439 閱讀 9929

判斷n是否為素數

續篩法部分

區間篩法

若乙個數可以進行因數分解,則得到的兩個數一定是有乙個≤x

\sqrt x

x​,另乙個≥x

\sqrt x

x​任何乙個數都可以拆分為若干個質因數的乘積,如6=2*3,7=1*7 。

複雜度o(nn

\sqrt n

n​)

#include

using namespace std;

intplainsieve

(int n)

return p;

}int

main()

複雜度 o(nlglgn)

解釋:當prime[i]為0時,說明 i 沒有被篩到過,即 i 為質數。質數總數 p++

之後要將 i 的n以內的倍數 j 全部置為合數,prime[j]標記為1。

此後若篩到 j ,prime為1,j 為合數,直接跳過,進行下個數的判斷

#define max 1000010

int prime[max]=;

interasieve

(int n)

}return p;

}

問題需改進:

有數被篩多次,如篩到3會把6,9,12,15……到 ≤n的3的倍數全部標記,

但是!篩到5的時候,會把5*3=1515又被重複標記

當然埃氏篩網上也有優化,但是還是會有重複篩選的情況,複雜度也不是最優

所以歐氏篩來了↓↓↓

複雜度o(n)

原理:(預備知識2)

所以讓乙個合數只被它的最小質因數篩去即可。

int prime[max]

;bool flag[max]

;int

eulersieve

(int n)

}return p;

}

隨便用個歐氏篩交到oj上就超時了

老老實實搬磚吧。

真香!嚶嚶嚶

當**更!▼▼▼

複雜度o(n

\sqrt n

n​)

#include

using namespace std;

bool is_prime

(int n)

intmain()

令n≥1

n≥1n≥

1,所有的正整數可表示為:1,2,4n−

14n-1

4n−1

,4 n4n

4n,4 n+

14n+1

4n+1

,4 n+

24n+2

4n+2

,4 n+

34n+3

4n+3

,4 (n

+1

)4(n+1)

4(n+1)

,……由此可知,當數為4n4n

4n,4 n+

24n+2

4n+2

,即4 ∗n

4*n4∗

n,2(2n

+1

)2(2n+1)

2(2n+1

)時,均為合數。

顯然質數只能在4n−

14n-1

4n−1

或4 n+

14n+1

4n+1

出現。

根據n能否整除4n−

14n-1

4n−1

或4 n+

14n+1

4n+1

即可

複雜度 o(n

3\frac

3n​​

)

bool is_prime

(int n)

return true;

}

寫(搬**)到這裡,突然發現上個博主寫的線性篩過了我沒過的那道題

我想回家種田……

怒三更?

[2019.1.29 00:51]

終於找到原因了?:

被陣列大小給騙了qaq:他說n≤10000000,我開到那麼大就re,多開10個就ac。?害我調**到凌晨

分析:直接求出小於b的所有質數,再算區間內的質數個數肯定是不行的,因為陣列可能開不到1012

10^10

12那麼大。

方法:由於b以內的合數的質因數不超過b

\sqrt b

b​,所以可以先打乙個[2,

b]

[2,\sqrt b]

[2,b​]

的質數表,在篩[2,

b)

[2,\sqrt b)

[2,b​)

的同時,用埃氏篩將區間[a,

b)

[a,b)

[a,b

)的倍數也同時篩掉。

此方法還用到下標偏

移\color

下標偏移

的方法來節省陣列空間。

特 別注

意a=1

或0時易

錯\color

特別注意a=

1或0時

易錯

#include

using namespace std;

#define max 10000010

bool is_prime[max]

;bool is_prime_small[max]

;long

long prime[max]

;long

long p=0;

//篩區間[a,b)的整數,is_prime[i-a]=flase表示i為素數,i-a為偏移值

void

segementsieve

(long

long a,

long

long b)

}//統計質數個數

for(

long

long i=

0;i(!is_prime[i]

) cout<<

(prime[p++

]=i+a)

<<

" ";

}int

main()

return0;

}

判斷n是否為素數

續篩法部分

區間篩法

終於寫玩了!(●ˇ∀ˇ●)

篩選法求n以內素數(質數)

設定乙個標誌陣列isprime,isprime i 的值是1就表示i是素數。開始陣列元素值全部為1劃掉k的倍數,就是把isprime 2 k isprime 3 k 置成0最後檢查isprime陣列,輸出isprime i 為1的那些i include include using namespace...

161 用厄拉多塞篩法求質數個數

西元前250年,希臘數學家厄拉多塞想到了乙個非常美妙的質數篩法,減少了逐一檢查每個數的的步驟,可以比較簡單的從一大堆數字之中,篩選出質數來,這方法被稱作厄拉多塞篩法 sieve of eeatosthese 具體操作 先將 2 n 的各個數放入表中,然後在2的上面畫乙個圓圈,然後劃去2的其他倍數 第...

篩法求n以內的素數

篩法求素數 把2到n中所有的數都列出來,然後從2開始,先劃掉n內所有2 的倍數,然後每次從下乙個剩下的數 必然是素數 開始,劃掉其n內的所有倍數。最後剩下的數,就都是素數。空間換時間,加快了計算速度。include include include include define maxn 100000...