判斷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複雜度 o(nn≥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
即可
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...