質數與約數

programmingysx發表於2024-06-29

質數與約數:

 

整除與約數

\(n\) 為非負整數,\(d\) 為正整數,若 \(\frac{n}{d}\) 為整數,則稱 \(d\) 整除 \(n\),記為\(d\mid n\)。此時,則稱 \(d\)\(n\) 的約數,或因數、因子;稱 \(n\)\(d\) 的倍數。

 

質數與合數的定義:

對於 \(n \geq 2\) ,若 \(\forall 1<i<n,i\nmid n\) ,則稱 \(n\) 為質數,否則 \(n\)​ 為合數。

 

質數判定:

試除法:

單次時間複雜度 \(O(\sqrt n\ )\)

程式碼
bool is_prime(int n) {
	if(n < 2)
		return false;
	for(int i=2; i<= sqrt(n); ++i) {
		if(n % i == 0)
			return false;
	}
	return true;
}

 

質數篩法一:

\(2\)\(n\) 列舉整數 \(i\),標記大於 \(i\) 且不大於 \(n\)\(i\) 的倍數。列舉到 \(i\) 時,若 \(i\) 沒有被標記過,則 \(i\) 為質數。

時間複雜度 \(O(\sum_{i=1}^n \frac{n}{i})=O(n\log n)\)

程式碼
void found_prime() {
	memset(vis, 0, sizeof(vis));
	vis[0] = 1; vis[1] = 1; // 特殊處理 0 和 1
	for(int i=2; i<=n; ++i) {
		for(int j=i*2; j<=n; j+=i)
			vis[j] = 1; // 標記合數
    }
}

 

埃氏篩:

只需要列舉質數的倍數就可以標記到所有合數了。實際上對於每個質數 \(p\) 而言,小於\(p^2\)\(p\) 的倍數在掃描到更小的質數時就已經被標記過了。

\(2\)\(n\) 列舉整數 \(i\),若 \(i\) 是質數,則把 \(i^2\) , \((i+1) \times i\), \(\cdots\), \(\lfloor \frac{n}{i}\rfloor \times i\) 標記為合數。列舉到 \(i\) 時,若 \(i\) 沒有被標記過,則 \(i\) 為質數。

時間複雜度 \(O(\sum_{pr[i]\leq n}\frac{n}{pr[i]})=O(n\log\log n)\)

程式碼
void found_prime() {
	memset(vis, 0, sizeof(vis));
	vis[0] = 1; vis[1] = 1; // 特殊處理 0 和 1
	for(int i=2; i<=n; ++i) {
		if(!vis[i]) { // i 為質數
			for(int j=i*i; j<=n; j+=i)
				vis[j] = 1; // 標記合數
		}
	}
}

 

線性篩:

用每一個合數的最小質因子來標記這個合數。時間複雜度 \(O(n)\)

程式碼
int pr[N],cnt;
bool vis[N];
void init(){
	int n=1e5+50;
	for(int i=2;i<=n;i++){
		if(!vis[i]){pr[++cnt]=i;}
		for(int j=1;j<=cnt&&i*pr[j]<=n;j++){
			vis[i*pr[j]]=1;
			if(i%pr[j]==0)break;
		} 
	}
}

 

區間篩:(埃氏篩)

程式碼
const int maxn = 1e6+10;
typedef long long LL;
bool is_prime[maxn];  //標記a~b範圍內的質數 
bool is_prime_small[maxn];  //標記 1~sqrt(n)範圍內的所有質數 
LL a, b;

//對區間[a, b]內的整數執行篩法,is_prime[i-a]=true表示i是素數 
void found_prime()
{
	for(LL i=0; i*i<=b; ++i)
		is_prime_small[i] = true; 
	is_prime_small[1] = false;
	for(LL i=0; i<=b-a; ++i)
		is_prime[i] = true;
		
	for(LL i=2; i*i<=b; ++i) {
		if(is_prime_small[i]) {  // i是質數 
			for(LL j=i*i; j*j<=b; j+=i)  // 標記 sqrt(b) 以內的i的倍數 
				is_prime_small[j] = false;
			for(LL j = max(2LL, (a+i-1)/i) * i; j<=b; j+=i)  //標記[a, b]中i的倍數 
				is_prime[j-a] = false;
		}
	}	
}

 

算術基本定理:

任何一個大於 1 的正整數都能唯一分解為若干個質數的乘積。

\(n\geq2\) 為整數,有唯一的分解式:

\[n=p_1^{c_1}\times p_2^{c_2}\times \cdots\times p_m^{c_m}=\prod_{i=1}^mp_i^{c_i} \]

其中 \(c_i\) 都是正整數,\(p_i\) 都是質數,且滿足 \(p_1\leq p_2\leq...\leq p_m\)

根據算術基本的定理,對於任意一個大於 \(2\) 的整數 \(n\),他的正約數集合可以寫作:

\[\{p_1^{b_1}\times p_2^{b_2}\times \cdots\times p_m^{b_m}\} (0\leq b_i\leq c_i) \]

推論一: \(n\) 的正約數個數為:

\[(c_1+1)\times (c_2+1)\times \cdots\times (c_m+1)=\prod_{i=1}^m(c_i+1) \]

推論二: \(n\) 的所有正約數之和為:

\[(1+p_1+p_1^2+...+p_1^{c_1})\times\cdots\times (1+p_m+p_m^2+...+p_m^{c_m})=\prod_{i=1}^m\sum_{j=0}^{c_i}p_i^j \]

 

階乘分解

對於一個數 \(n\)\(n!\) 的質因數分解:

考慮對於一個質數 \(p_i\)\(n!\) 中包含多少個 \(p_i\)
答案是 \(\sum_{i=1}^{\lfloor\log_pn\rfloor}\lfloor\frac{n}{p^i}\rfloor\)
對於每一個質數都用如上方式
共有 \(\frac{n}{\ln n}\) 個數,每次處理 \(\log n\) 的複雜度,總複雜度 \(O(n)\)

 

求解正約數集合:

試除法 求 \(n\) 的正約數:

時間複雜度 \(O(\sqrt n )\)

程式碼
int divisor[10010], cnt = 0;
for(int i=1; i<=sqrt(n); ++i) {
	if(n % i == 0) {
		divisor[++cnt] = i;
		if(i != n/i) divisor[++cnt] = n/i;
	}
}

推論:一個整數 \(n\)的正約數個數最多不超過 \(2\times \sqrt n\)

 

倍數法 求\(1\sim n\)的正約數:

先列舉 \(1 \sim n\) 中的每一個數作為約數 \(d\),再在 \(1\sim n\) 尋找 \(d\) 的倍數即可。時間複雜度 \(O(n+\frac{n}{2}+\cdots+\frac{n}{n})=O(n\log n)\)

程式碼
vecotr<int> divisor[500010];
for(int i=1; i<=n; ++i) { // 先列舉約數 i
	for(int j=1; j<=n/i; ++j) //列舉 i 在 1~n 範圍內的倍數 i × j
		divisor[i*j].push_back(i); // i 是 i × j 的約數
}

推論:\(1\sim n\) 的約數個數總和大約為 \(n\log n\) 個。

 

約數研究

\(f(x)\)\(x\) 的約數個數,求 \(\sum_{i=1}^nf(i)\)

可以列舉每一個 \(i\in[1,n]\)\(1\sim n\) 中含有 \(\lfloor\frac{n}{i}\rfloor\) 個約數 \(i\) 。所以答案為 \(\sum_{i=1}^n\lfloor\frac{n}{i}\rfloor\)

 

\({\rm gcd}\) :

\(\forall a,b\in \mathbb{N},d\in \mathbb{N^{*}}\)\(d\mid a\ \&\ d\mid b\) 則稱 \(d\)\(a,b\) 的公約數。

\(a,b\) 的公約數中最大的稱為 \(a,b\) 的最大公約數,記為 \(\gcd(a,b)\)

性質:

  • \(\gcd(a,b)=\gcd(b,a)\)
  • 對於 $\forall a,b\in \mathbb{N} $ 若 \({\rm gcd}(a,b)=1\) 則稱 \(a,b\) 互質。
  • 由於任何正整數都是 \(0\)\(0\) 的公約數,故 \(\gcd (0,0)\) 不存在。
  • 對於 \(\forall a\in \mathbb{N^{*}}\) ,有 \(\gcd(a,a)=a,\gcd(a,0)=a\)
  • \(\forall k\in \mathbb{Z}\),有 \(\gcd(k\times a,k\times b)=k\times \gcd(a,b)\)

 

更相減損術:

\(\forall a,b\in \mathbb{N^{*}}\ \&\ a\geq b\)\(\gcd(a,b)=\gcd(b,a-b)=\gcd(a,a-b)\)

\(\forall d\mid a\ \&\ d\mid b\),有 \(a=k_1\times d,b=k_2\times d\) ,則 \((a-b)=(k_1-k_2)\times d\) ,所以 \(d\) 也是 \(b,a-b\) 的公約數,所以 \(\gcd(a,b)=\gcd(b,a-b)\)​ 。

 

輾轉相除法:

\(\forall a,b\in \mathbb{N^{*}}\ \&\ b!=0\)\(\gcd(a,b)=\gcd(b,a\bmod b)\)

  • \(a<b\) ,則 \(\gcd(b,a\bmod b)=gcd(b,a)=gcd(a,b)\)
  • \(a\geq b\) ,設 \(a=q\times b+r\) ,其中 \(0\leq r <b\)\(r=a\bmod b\) 。有 \(a=k_1\times d,q\times b=k_2\times d\) ,則 \(r=(a-q\times b)=(k_1-k_2)\times d\) ,因此 \(d\) ,也是 \(b,r\) 的公約數,故 \(\gcd(a,b)=\gcd(b,a\bmod b)\)

程式碼:

程式碼
int gcd(int a, int b) {
	while(b > 0 ) {
		int x = a % b;
		a = b;
		b = x;
	}
	return a;
}

遞迴:

程式碼
int gcd(int a, int b) {
	return b ? gcd(b, a%b) : a;
}

最大複雜度 \(O(\log(a+b))\)

 

\({\rm lcm}\)

\(\forall a,b\in\mathbb{N^{*}},m\in \mathbb{N}\)\(a\mid m\ \&\ b\mid m\),則稱 \(m\)\(a\)\(b\) 的公倍數。

\(a,b\) 的公倍數中最小的稱為 \(a,b\) 的最小公倍數,記為 \({\rm lcm}(a,b)\)

\[{\rm lcm}(a,b)=\frac{a\times b}{\gcd(a,b)} \]

實際程式碼中: \({\rm lcm(a,b)=\frac{a}{\gcd(a,b)}\times b}\)

 

gcd與lcm

給出某兩個整數 \(a\)\(b\)\(a\leq b\))的最大公約數 \(GCD\) 和最小公倍數 \(LCM\) ,請找出滿足的 \(a\)\(b\) ,使得 \(b-a\) 的值最小。

\(\because LCM=\frac{a\times b}{GCD}\)
\(\therefore \frac{a\times b}{GCD^2}=\frac{LCM}{GCD} \Rightarrow (\frac{a}{GCD})^2\leq \frac{LCM}{GCD}\)
\(\therefore \frac{a}{GCD}\leq \sqrt{\frac{LCM}{GCD}}\)
\(a'=\frac{a}{GCD}\) ,從 \(\sqrt{\frac{LCM}{GCD}}\sim 1\) 來列舉 \(a'\) ,當 \(a'\mid \frac{LCM}{GCD}\&\& \gcd(a',LCM/GCD/a')=1\) 時停止列舉。
答案即為 \(a=a'\times GCD,b=\frac{LCM}{a'}\)

 

CF1152C

給定兩個正整數 \(a,b\) ,找到非負整數 \(k\) 使 \(a+k\)\(b+k\) 的最小公倍數最小,如有多解輸出最小的 \(k\)

\(a>b\) 顯然 \({\rm lcm}(a+k,b+k)=\frac{(a+k)(b+k)}{\gcd(a+k,b+k)}\)
由輾轉相除法可知 \(\gcd(a,b)=\gcd(b,a-b)\)
所以 \({\rm lcm}(a+k,b+k)=\frac{(a+k)(b+k)}{\gcd(b+k,a-b)}\)
所以可以列舉 \(a-b\) 的因子 \(w\) ,若 \(b\%w=0\)\(k=0\) ,否則 \(k=(\lfloor\frac{b}{w}\rfloor+1)w-b\)

相關文章