講丶數學
壹 回顧小學數學
素數定義:
素數是指在大於1的自然數中,除了1和它本身以外不再有其他因數的自然數。
約數定義:如果存在一個整數\(k\),使得\(a=k*d\),則稱\(d\)整除\(a\),記做\(d|a\),稱\(a\)是\(d\)的倍數,如果\(d>0\),稱\(d\)是\(a\)的約數。特別的任何數都整除\(0\)。
合數定義:
合數是指自然數中除了能被1和本身整除外,還能被其他數(0除外)整除的數。
質數個數:
在自然數中,質數的個數並不多,對於一個足夠大的整數\(N\),不超過\(N\)的質數大約有\(N/lnN\)個。(證明很復雜,自己上網找,理解不了就記下來)
算數基本定理:
任何一個大於1的正整數都能唯一分解為有限個質數的乘積。
\(N=p_1^{c_1}p_2^{c_2}p_3^{c_3}p_4^{c_4}……p_m^{c_m}\)
其中\(c_i\)都是正整數,\(p_i\)都是質數,且\(p_1<p_2<p_3……<p_m\).
算數基本定理的推論:
由上面的定理可知\(N\)的正約數集合可寫作:
{\(p_1^{b_1}p_2^{b_2}……p_2^{b_2}\)},且\(0<=b_i<=c_i\)
\(N\)的正約數個數為\((c_1+1)(c_2+1)*……*(c_m+1)=\prod_{i=1}^m(c_i+1)\)
正約數和為\(\prod_{i=1}^m(\sum_{j=0}^{c_i}(p_i)^j)\)
貳 質數的判定
暴力試除:
若一個正整數\(N\)為合數,則存在一個能整除\(N\)的數\(T\),且\(2<=T<=\sqrt{N}\).
所以我們暴力掃描\(2\)~\(\sqrt{N}\)的整數,若都不能整除\(N\),\(N\)就是質數。同時要特判0和1兩個數,它們既不是質數,也不是合數。
叄 質數篩法
Eratosthenes 篩法(埃拉托斯特尼篩法):
如果\(x\)為合數,那么\(x\)的倍數一定是合數。
我們可以根據上面的命題,由小到大掃描每個數\(x\),把\(2x,3x,4x……\lfloor N/x \rfloor*x\)打上標記,記為合數。當掃描到某個數后,如果沒被標記,它就是合數。
這個算法的時間復雜度是\(O(\sum_{質數p<=N}N/p)=O(NloglogN)\),很接近線性,一般競賽里都用這個方法。
線性篩法:
我們想一下,按照埃篩的方法標記的時候,會出現重復標記的情況。
比如12,它在標記2的倍數時被標記了一次,在標記3的倍數時被標記了一次。
線性篩是通過從小到大儲存質因子來標記合數。
設數組\(pf\)記錄每個數的最小質因子,按照下面的步驟來操作:
- 依次考慮2~\(N\)之間的每個數\(i\);
- 若\(pf[i]=i\),則\(i\)是質數;
- 掃描不大於\(v[i]\)的每個質數\(p\),令\(pf[i*p]=p\).
這樣每個合數\(i*p\),只會被最小質因數\(p\)標記一次,時間復雜度為\(O(N)\);
