素數:因數只有 1 和它自己的數。只有兩個因數的數。
合數:除了素數和 1 的數。/ 因數 $>2$。
假設現在有一個合數 $x$。$x$ 一定是由若干個小於它的質數組成的(分解質因數)。
Q1:如何判斷一個數 $x$ 是不是素數?
如果 $x$ 只有兩個因數($1$ 和 $x$)說明它是素數。
假如說 $x$ 是合數,那么 $x$ 除了 $1$ 和 $x$ 這兩個因數必定至少還有一個因數 $y$。那么 $2≤y≤x-1$ 。那 $y$ 有三種情況:$\begin{cases}y<\sqrt{x}\\y=\sqrt{x}\\y>\sqrt{x}\end{cases}$
不管是這三種的哪一個,我們都可以看出來 $\dfrac{x}{y} / y \le \sqrt{x}$ (必定有一個因數是 $\le \sqrt{x}$),就是說只要 $x$ 是合數,那么一定能找到一個因數 $y$,$2 \le y \le \sqrt{x}$。反過來說,如果一個數 $x$ 找不到在 $2$ ~ $\sqrt{x}$ 范圍里能整除 $x$ 的一個數 $y$,那 $x$ 就不是合數,是質數。($1$ 除外)
所以說,我們想判斷 $x$ 是不是質數,只需要在 $2$ ~ $\sqrt{x}$ 這個范圍里找一個能整除 $x$ 的數 $y$,如果能找到,就說明 $x$ 是合數,找不到,就說明 $x$ 是質數。
程序:
#include<bits/stdc++.h>
using namespace std;
int x;
int main(){
cin >> x;
if(x == 1){
cout << "No";
return 0;
}
for(int i=2; i<=sqrt(x); i++){
if(x%i == 0){
cout << "No";
return 0;
}
}
cout << "Yes";
return 0;
}
關於互質:
定義:如果 $a$ 和 $b$ 互質,則 $(a,b)=1$。($a$ 和 $b$ 只有一個公約數 $1$)
相鄰的兩個數互質。因為兩個不互質的數至少至少也要相差 $2$,然而相鄰的兩個數相差 $1$。
歐拉函數:(互質拓展)
對正整數
$n$,歐拉函數是小於 $n$ 的正整數中與 $n$ 互質的數的數目。
$φ(n)=n(1-\dfrac{1}{p_1})(1-\dfrac{1}{p_2})(1-\dfrac{1}{p_3})(1-\dfrac{1}{p_4})...\times (1-\dfrac{1}{p_k})$
$P_i$ 表示 $n$ 的質因數。
證明:(我的理解,可能不太嚴謹)
- 假如現在有一個數 $x$,那么 $x$ 和 $n$ 的公約數只有一個 $1$。
- 那我們先把 $n$ 分解質因數,$p_1,p_2,p_3....p_k$,我們不能讓 $x$ 擁有因數 $p_i$。$(1 \le i \le k)$
- 我們現在要求的就是 $n$ 里面有多少個數的因數不含 $p_1,p_2,p_3...p_k$ ,這些數的個數。
- 我們先考慮不含 $p_1$ 的數的個數,這個很好求,是 $n(1-\dfrac{1}{p_1})$。可以理解為每 $p_1$ 個數就會有一個 $p_1$ 的倍數。(比如 $2$,每兩個數中就有一個 $2$ 的倍數)
- 然后我們要在這不含 $p_1$ 的數中再篩出來也不含 $p_2$ 的數的個數。那就是 $n(1-\dfrac{1}{p_1}) \times (1-\dfrac{1}{p_2})$。
- 然后一直乘到 $p_k$。