数论(一)——素数,GCD,LCM
這是一個(gè)數(shù)論系列:)
一、素?cái)?shù)
×費(fèi)馬小定理
Theorem:?設(shè) p 是一個(gè)素?cái)?shù),a 是一個(gè)整數(shù)且不是 p 的倍數(shù),那么
很遺憾,費(fèi)馬小定理的逆定理是不成立的。對(duì) a = 2,滿足的非素?cái)?shù) n 是存在的。
比如 n = 341 = 11 × 31
對(duì)于整數(shù) a,稱滿足的合數(shù)為以 a 為底的偽素?cái)?shù)。
經(jīng)測(cè)試,
前 10 億的自然數(shù)中,同時(shí)以 2 和 3 為底的偽素?cái)?shù)有 1272 個(gè)。
我們用費(fèi)馬小定理驗(yàn)證素?cái)?shù)的話,出錯(cuò)的概率大概只有 0.000025。
×Miller-Rabin
Theorem:.若 p 是素?cái)?shù),x 是一個(gè)正整數(shù),且 ?那么。
Corollary:設(shè)待測(cè)數(shù)為 n,取一個(gè)比 n 小的正整數(shù) a,設(shè),若 n 是素?cái)?shù),則要么,要么存在一個(gè) i,滿足 0 ≤ i < r 且?。
Solution:隨機(jī)選取 k 個(gè)小于待測(cè)整數(shù) n 的正整數(shù)作為底 a,用上面那個(gè)推論的逆定理來測(cè)試。時(shí)間復(fù)雜度O(k?log?n)。
這種方法仍是有反例的,但是若選擇 2 和 3 為底,第一個(gè)反例就大到了 1373653。
Example:給出一個(gè)正整數(shù)n, 求不超過n的所有素?cái)?shù)。
Solution:
1.枚舉1-n的所有數(shù)做素?cái)?shù)測(cè)試, 時(shí)間復(fù)雜度是O(n log n)。
2.逐次枚舉 2 到 n,設(shè)當(dāng)前枚舉到 x,那么對(duì)所有滿足把標(biāo)記為非素?cái)?shù)。時(shí)間復(fù)雜度 O(n log n)。
3.線性篩法:
memset(not_prime, 0, sizeof(not_prime));
not_prime[1] = true;
for (int i = 2; i <= n; ++i)
{if (!not_prime[i]) prime[++ prime_count] = i;for (int j = 1; j <= prime_count; ++j){if (prime[j] * i > n) break;not_prime[prime[j] * i] = true;if (i % prime[j] == 0) break;}
} 關(guān)鍵在倒數(shù)第3行,它保證了我們總是能夠找到每個(gè)數(shù)的最小的那個(gè)素因子。因?yàn)槊總€(gè)不小于1 的整數(shù)的最小素因子個(gè)數(shù)是 1,所以復(fù)雜度是 O(n)。
×唯一分解定理
Theorem:每個(gè)大于1的整數(shù)均可分解為有限個(gè)素?cái)?shù)的乘積, 并且若不計(jì)因子在分解中的次序, 則這種分解式是唯一的。
二、GCD 和 LCM
×Definition(GCD,LCM):略。
×Example: 給兩個(gè)正整數(shù)a, b, 求他們的最大公約數(shù)和最小公倍數(shù)。
×Solution:歐幾里得算法
int Gcd(int a, int b)
{if (b == 0) return a;else return Gcd(b, a % b);
}求 n 個(gè)不超過 m 的正整數(shù)的最大公約數(shù)的復(fù)雜度是 O(n + log m)。×Example:?求不定方程?ax + by = m 的整數(shù)解。
×Theorem:ax+ by = m 有整數(shù)解當(dāng)且僅當(dāng) (a, b)|m。
×Theorem:設(shè) (x0 , y0 ) 是不定方程 ax + by = m 的一組解,?(a, b) = g,那么全部解為,其中t為所有整數(shù)。
×Solution(擴(kuò)展歐幾里得算法)
int ExGcd(int a, int b, int &x, int &y)
{if (b == 0) {x = 1, y = 0;return a;}else {int g = ExGcd(b, a % b, x, y);int t = x;x = y, y = t - a / b * x;return g;}
} 考慮從 bx + (a mod b)y = g 的 (x, y) 推導(dǎo)到 ax′ + by′ = g 的 (x′ , y′ )。
以NOIp2012提高組Day2Mod一題為例子:
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
int exgcd(int a, int b, int &x, int &y)
{if (b == 0){x = 1, y = 0;return a;}else{int g = exgcd(b, a % b, x, y);int t = x;x = y, y = t - a / b * x;return g;}
}int main()
{int a, b, x, y, d;scanf("%d%d", &a, &b);d = exgcd(a, b, x, y);if (d == 1) printf("%d\n", (x % b + b) % b);return 0;
} ×Example:求解一次同余方程組
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
×Solution:當(dāng)mi兩兩互素時(shí), 是經(jīng)典的中國剩余定理, 請(qǐng)自行百度或Google。
×Solution:介紹一種基于“合并”思想的算法, 當(dāng)mi不滿足兩兩互素時(shí), 也同樣能夠工作
可以寫成
設(shè) g = gcd(m1, m2), 若b2 - b1 能被g整除,則可以繼續(xù)
用擴(kuò)展歐幾里得算法算出,則兩個(gè)同余式可以合并為
×Definition(逆元):設(shè)正整數(shù)模m, 對(duì)于任意正整數(shù)a滿足(a, m) = 1, 總存在惟一的b滿足?且?, 稱b為模m意義下a的逆元。其實(shí),嚴(yán)格意義上講b屬于模m的一個(gè)縮系。
×Example:給出正整數(shù)a 和 m,保證 (a, m) = 1,求模 m 意義下 a 的逆元。
×Solution:根據(jù)定義用擴(kuò)展歐幾里得解一個(gè)線性同余方程即可
注意到 a × b ≡ 1 (mod m) 可以認(rèn)為是 ,所以當(dāng)我們需要在模 m意義下除以 a 時(shí),可以用乘上 b 來代替,這就是逆元的用途。
轉(zhuǎn)載于:https://www.cnblogs.com/joker0429/archive/2013/01/11/2909923.html
總結(jié)
以上是生活随笔為你收集整理的数论(一)——素数,GCD,LCM的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: javamail gmail
- 下一篇: apue读书笔记-第十二章