今天正式學了一遍質數篩(已經可以打線性的質數篩了!)以及質因數分解,要做乙個小小的總結。
質數:除了1和它本身沒有其他的因數,一般指的都是正整數。;
篩法:篩法是一種簡單檢定素數的演算法。
篩法的具體做法:給出要篩數值的範圍n,找出n以內的素數p1,p2,p3,…,pk。先用2去篩,即把2留下,把2的倍數剔除掉;再用下乙個素數,也就是3篩,把3留下,把3的倍數剔除掉;接下去用下乙個素數5篩,把5留下,把5的倍數剔除掉;不斷重複下去…。
唯一分解定理:任何乙個大於1的正整數都能夠被唯一分解為有限個質數的乘積。
對於質數篩而言,我們有三種做法:
根據定義出發:若是我們除了1和它本身找到了其他的因子,那麼這個數字一定不是質數,反之,則為質數。
那麼,對於0和1本身,我們既要進行特殊判斷,他們既不是質數也不是合數。
列舉因數的時候我們只需要列舉到根號即可,因為這樣就可以判斷他的所有的因數。(自行思考……)
bool
primes
(int x)
上面的方法是我們直接判斷該數字是不是質數,這樣的話,我們每次只可以判斷乙個數字,效率極低。
那,我們想一下,是否可以直接找出乙個範圍裡的質數呢??
如果找質數不好找的話,我們可以通過找合數啊,正難則反,若是合數都被找出來了,那麼最後剩下來的不就都是質數了嗎?
那麼,我們就可以通過已知的質數(2,3,5……)去標記合數。
從2開始,由小到大掃瞄每乙個數字x,把他的倍數2x,3x,4x……都標記為合數。若掃瞄到乙個數字未被標記,則他便不能被(2,x-1)的數字整除,所以該數字就是質數。
我們可以再繼續想一下:對於6而言,他會被2,3標記兩次(效率極低)……,實際上,小於x
2x^2
x2的x的倍數在掃瞄更小的數字的時候就已經被標記過了。所以,我們對於數字x而言,我們從x^2開始標記就可以了。
void
primes
(int x)
}
雖然在上面的演算法中有小小的優化,但是同樣還是不可以改變量字會被該演算法同時好多次標記的本質,比如12,36,60,120……這些數字同樣會被2,3……同時進行標記……
所以,我們考慮被進一步的優化。
考慮數字x的因數的唯一確定方法:我們可以採用x的最小的質因數的乘積。比如:12=2
∗2∗3
,6=2
∗3
12=2*2*3, 6=2*3
12=2∗2
∗3,6
=2∗3
……這樣子的話,我們就唯一確定了x的被遍歷的方法,所以該數字就只會被遍歷一次。
線性篩法的原理:每個合數必有乙個最小的質因數的排列方式,用這排列方式把這個合數篩掉。
在每一把該數字的最小的質因子篩完之後,再次遍歷到該數字的因數,便可以保證這個因數一定是質因數。(自行思考,還是比較好想的。)
void
primes
(int x)
}}
我們用上面的試除法以及eratosthenes 篩法,找到 [2,x
\sqrt
x]中x的所有的因子,並且把該因子在x中全部除盡,使得x中沒有了該因子的參與。
比如:12=2
∗2∗3
12=2*2*3
12=2∗2
∗3,那麼,對於12而言,我們就需要把兩次2都除盡,使得12中只剩下了3的參與。
那麼,顯然,在上述的過程中可以整除x的數字都是質數。
void
primes
(int k,
int x)
if(x!=
1) c[x]++;
}
主義在判斷的時候要有特判:0,1既不是質數也不是合數;
判斷單個數字是不是質數的時候一般用試除法,判斷多個變數的時候用的是eratosthenes 篩法和線性篩法;
試除法列舉到n
\sqrt
n;eratosthenes 篩法(合數標記)的第二重迴圈列舉到n
i\frac
in;
線性篩法是找出所有的數字中最小的唯一的質因數分解。
推薦題目:(注意問題的轉化,有些問題有一些拔高,謹慎選做。)
p3383 【模板】線性篩素數
質數距離
階乘分解
調整公約數
完……
質因數分解
題目16 將乙個正整數分解質因數。例如 輸入90,列印出90 2 3 3 5。程式分析 對n進行分解質因數,應先找到乙個最小的質數k,然後按下述步驟完 成 1 如果這個質數恰等於n,則說明分解質因數的過程已經結束,列印出即可。2 如果n k,但n能被k整除,則應列印出k的值,並用n除以k的商,作為新...
質因數分解
短除法 求乙個數分解質因數,要從最小的質數除起,一直除到結果為質數為止。分解質因數的算式的叫短除法 和除法的性質差不多,還可以用來求多個個數的公因式 求 最大公因數的一種方法,也可用來求 最小公倍數。求幾個數最大公因數 的方法,開始時用觀察比較的方法,即 先把每個數的因數找出來,然後再找出公因數,最...
質因數分解
講乙個數分解為幾個質數相乘的結果 int a maxn 用來存質因數 int b maxn 用來存質因數的個數 int main if n 1 不能忘記這一步操作 輸出 第1種寫法 a a a b b b b c c printf 第一種寫法 for int i 1 i tot i else pri...