基礎數論
Update: 2024/11/02。
素數
素數和合數
定義
若 \(p \in \Zeta\),且 \(p \not= 0, \pm1\),其約數集合中的元素只有 \(1\) 和 \(p\) 本身,那麼稱 \(p\) 為素數。
若 \(a \in \Zeta\),且 \(a \not= 0, \pm1\), \(a\) 不為素數,則為合數。
素數一般指正的素數。
素數計數
\(\pi(x)\) 表示小於或等於 \(x\) 的素數個數。隨 \(x\) 增大,近似結果:
\(\pi(x) \sim \frac{x}{\ln(x)}\)。
$ 10^9 $ 以內的數字,約數個數最多的數字的約數為 \(1536\) 個。
素數判定
試除。列舉 \(1 \sim \sqrt{n}\) 整數,看是否能夠整除。
bool isPrime(a) {
if (a < 2) return 0;
for (int i = 2; i * i <= a; ++i)
if (a % i == 0) return 0;
return 1;
}
素數篩法
-
埃氏篩
對於任意大於 \(1\) 的正整數 \(n\) ,那麼它的 \(x\) 倍為合數\((x > 1)\)。
如果我們從小到大考慮每個數,然後同時把當前這個數的所有(比自己大的)倍數記為合數,那麼執行結束的時候沒有被標記的數就是素數了。
vector<int> prime;
bool is_prime[N];
void Eratosthenes(int n) {
is_prime[0] = is_prime[1] = false;
for (int i = 2; i <= n; ++i)
is_prime[i] = true;
int x = sqrt(n);
for (int i = 2; i <= x; ++i) {
if (is_prime[i])
for (int j = i * i; j <= n; j += i)
is_prime[j] = false;
}
for (int i = 2; i <= n; ++i)
if (is_prime[i])
prime.push_back(i);
}
時間複雜度為 \(\Omicron(n \log \log n)\)。
-
線性篩
可以注意到, 埃氏篩法仍有最佳化空間,它會將一個合數重複多次標記。
讓每個合數都只被標記一次即可。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e8+10;
const int maxm = 1e7;
int v[maxn],prime[maxm]; // v[i] 表示 i 的最小質因子
int n, q, cnt=0;
void is_prime() { // 線性篩
memset(v, 0, sizeof(v));
for(int i=2; i<=n; ++i) {
if( !v[i] ) {
v[i] = i;
prime[++cnt] = i;
}
for(int j=1; j<=cnt; ++j) {
if(prime[j] > v[i] || prime[j] > n/i)
break;
v[i*prime[j]] = prime[j];
}
}
}
int main() {
scanf("%d%d", &n, &q);
is_prime();
while(q--) {
int x;
scanf("%d", &x);
printf("%d\n", prime[x]);
}
return 0;
}
-
區間篩法
using ll = long long;
bool isprime[maxn], primepart[maxn];
void func(ll l, ll r) {
for (ll i = 0; i * i <= r; ++i)
primepart[i] = 1;
primepart[1] = 0;
for (int i = 0; i <= r - l; ++i)
isprime[i] = 1;
for (ll i = 2; i * i <= r; ++i) {
if (primepart[i]) {
for (ll j = i * i; j * j <= r; j += i)
primepart[j] = 0;
for (ll j = max(2ll, (l + i - 1) / i) * i; j <= r; j += i)
isprime[j - l] = 0;
}
}
int ans = 0;
for (ll i = l; i <= r; ++i)
if (isprime[i - l] && i != 1)
ans++;
printf("%d\n", ans);
return;
}
相關題目
- 素數密度
質因子分解
由唯一分解定理得。
void divide(int n) {
m = 0;
int t = sqrt(n);
for(int i=2; i<=t; ++i) {
if(n % i == 0) { // 此處能整除n的i一定是質數
p[++m] = i; c[m] = 0;
while(n % i == 0) {
n /= i; c[m]++;
}
}
}
if(n > 1) { // 原始的n是質數或者原始的n中最大的質因子大於 sqrt(n)
p[++m] = n; c[m] = 1;
}
}
約數
定義
若 $n \in $ \(\Zeta\),$d \in $ $ \Zeta $, \(n\) \(\%\) \(d\) \(=\) \(0\),則稱 \(d\) 是 \(n\) 的約數,\(n\) 是 \(d\) 的倍數,記作 $ d \mid n $。
算數基本定理
引理
設 \(p\) 是素數,\(p | a_1a_2\),那麼 \(p | a_1\) 和 \(p|a_2\) 至少有一個成立。
唯一分解定理
設有 \(a \in \Nu^*\),那麼其一定可以表示為若干個素數的乘積。
標準素因數分解式
設有 \(a \in \Nu^*\),必有:
\(a=p_1^{c_1}p_2^{c_2}...p_m^{c_m}, p_1 < p_2 <...< p_m\)
稱為正整數 \(a\) 的標準素因數分解式。
算數基本定理與算數基本引理,兩個定理等價。
對 n! 質因子分解
考慮到 \(1\sim n\) 中一個質數 \(p\) 出現次數為 \(\lfloor \frac{n}{p} \rfloor +\lfloor \frac{n}{p^2} \rfloor+\lfloor \frac{n}{p^3} \rfloor \dots \lfloor \frac{n}{p^c} \rfloor\)。
可在求大陣列合數時使用。
int get_sum(int x, int y) {
int sum = 0;
while (x) {
sum += x / y;
x /= y;
}
return sum;
}
算數基本定理的推論
在算數基本定理中,若 \(n \in \Nu^*\) 被唯一分解為 \(n = p_1^{c_1}p_2^{c_2}...p_m^{c_m}\),其中 \(c_i \in \Nu^*\),\(p_i\) 都是質數,且滿足 \(p_1 < p_2 < ...<p_m\),則 \(n\) 的正約數集合可寫作:
{\(p_1^{b_1}p_2^{b_2}...p_m^{b_m}\)} ,\(0 \leq b_i \leq c_i\)
\(n\) 的正約數個數為:
\(\prod\limits^{m}_{i=1}\big( \sum\limits^{c_i}_{j=0}(p_i)^j \big)\)
求\(N\) 的正約數集合——試除法
若 \(d \geq \sqrt{N}\) 是 \(N\) 的約數,則 $ d \mid N$ 也是 \(N\) 的約數。也就是說,除完全平方數外,約數總是成對出現的。
據此可得:
vector<int> res;
int n;
int main(){
cin >> n;
for(int i = 1; i <= n / i; i ++)
if(n % i == 0){
res.push_back(i);
if(i < n / i)
res.push_back(n / i);
}
for(auto t : res) cout << t << ' ';
return 0;
}
時間複雜度為 \(\Omicron(\sqrt{N})\)。
試除法的推論
對於一個 \(n \in \Zeta\),其約數個數的上界為 \(2 \sqrt{n}\)。
求 \(1 \sim N\) 每個數的正約數集合——倍數法
vector<int> factor[500010];
inline void bei(int n){
for(int i=1;i<=n;i++)
for(int j=1;j<=n/i;j++)
factor[i*j].push_back(i);
for(int i=1;i<=n;i++){
for(int j=0;j<factor[i].size();j++)
printf("%d ",factor[i][j]);
puts("");
}
}
時間複雜度為 \(\Omicron(N +N/2+N/3+...+N/N)=\Omicron(N\log{N})\)。
倍數法的推論
\(1 \sim N\) 每個數的約數個數總和大約為 \(N\log{N}\)。
例題
- [POI2001] [HAOI2007] 反素數
最大公約數
定義
若自然數 \(d\) 同時是自然數 \(a\) 和 \(b\) 的約數,則稱 \(d\) 是 \(a\) 和 \(b\) 的公約數。
在所有 \(a\) 和 \(b\) 的公約數中最大的一個數稱為 \(a\) 和 \(b\) 的最大公約數。記作 \(\gcd(a, b)\)。
若自然數 \(d\) 同時是自然數 \(a\) 和 \(b\) 的倍數,則稱 \(d\) 是 \(a\) 和 \(b\) 的公倍數。
在所有 \(a\) 和 \(b\) 的公倍數中最大的一個數稱為 \(a\) 和 \(b\) 的最大公倍數。記作 \(\text{lcm}(a, b)\)。
同理即可定義多個數的最大公約數與最大公倍數。
定理
\(\forall a,b \in \Nu, \gcd(a,b)*\text{lcm}(a,b)=a*b\)。
九章算術·更相減損術
\(\forall a, b \in \Nu,a \geq b\),有 \(\gcd(a, b) = \gcd(b, a - b) = \gcd(a, a - b)\)。
\(\forall a, b \in \Nu\),有 \(\gcd(2a, 2b) = 2\gcd(a, b)\)。
歐幾里德演算法
\(\forall a, b \in \Nu, b \not= 0, \gcd(a,b) = \gcd(b, a \% b)\)。
由此可得求 \(\gcd\) 的程式碼實現:
int gcd(int a, int b) {
return b ? gcd(b, a%b) : a;
}
時間複雜度為 \(\Omicron(\log(a+b))\)。
由於高精除法(取模)不容易實現,可考慮用更相減損術代替。
例題
- gcd與lcm
- Neko does Maths
互質
定義
\(\forall a, b \in \Nu\),若 \(\gcd(a, b)=1\),則稱 \(a,b\) 互質,記作 \(a \bot b\)。
對於多個數字,\(\gcd(a,b,c)=1\) 稱為 \(a,b,c\) 互質。把 \(\gcd(a,b)=\gcd(a,c)=\gcd(b,c)=1\) 稱為 \(a, b, c\) 兩兩互質。
積性函式
定義
若函式 \(f(x)\) 滿足 \(f(1)=1\) 且 \(\forall a, b \in \Nu^*, a \bot b\),都有 \(f(ab)=f(a)f(b)\),則稱 \(f(x)\) 為積性函式。
若函式 \(f(x)\) 滿足 \(f(1)=1\) 且 \(\forall a, b \in \Nu^*\),都有 \(f(ab)=f(a)f(b)\),則稱 \(f(x)\) 為完全積性函式。
尤拉函式
定義
尤拉函式(Euler's totient function ),即 \(\varphi(x)\),表示小於等於 \(n\) 的數字中與 \(n\) 互質的的數字個數。
尤拉函式為積性函式。
性質
- 根據唯一分解定理,設 \(n=\prod\limits^{m}_{i=1}p_i^{c_i}\),則 $\varphi(n)=n \times \prod\limits^{m}_{i=1}(1-\frac{1}{p_i}) $。
證明
若 \(n\) 的質因子個數為 \(2\),為 \(p_1,p_2\)。
設一個數的質因子集合為 \(\mathbb{A}\),另一個數的質因子集合為 \(\mathbb{B}\),那麼若兩數互質,則必滿足 \(\mathbb{A} \cap \mathbb{B} = \phi\)。
所以若一個數與 \(n\) 互質,則它的質因子集合中一定不包含 \(p_1,p_2\)。
所以 \(1 \sim n\) 中與 \(n\) 互質的數字一定不是 \(p_1, p_2\) 的倍數。
因此 \(1 \sim n\) 中與 \(n\) 互質的數字個數為 \(n-\frac{n}{p_1}-\frac{n}{p_2}+\frac{n}{p_1p_2}\)。
之所以需要加上一個 \(\frac{1}{p_1p_2}\),是因為在去除 \(n\) 中 \(p_1,p_2\) 倍數時多去除了一遍 \(n\) 中 \(p_1p_2\) 的倍數,需要再加回來。
也就是二元容斥原理。
當 \(n\) 的質因子個數大於 \(2\) 時,則涉及多元容斥原理。
\(n-\frac{n}{p_1}-\frac{n}{p_2}+\frac{n}{p_1p_2}=n(1-\frac{1}{p_1} )(1-\frac{1}{p_2} )\)。
所以此時 \(\varphi(n)=n(1-\frac{1}{p_1} )(1-\frac{1}{p_2})\)。
同理可得,當 \(n\) 的質因子個數為 \(3\),為 \(p_1,p_2,p_3\) 時,
\(\varphi(n)=n(1-\frac{1}{p_1} )(1-\frac{1}{p_2})(1-\frac{1}{p_3})\)。
歸納可得,若 \(n=\prod\limits^{m}_{i=1}p_i^{c_i}\),則 \(\varphi(n)=n \times \prod\limits^{m}_{i=1}(1-\frac{1}{p_i})\)。
證畢.
- \(1 \sim n\) 中與 \(n\) 互質的數字和為 $\frac{n}{2} \varphi(n) $。
證明
在 \(1\sim n\) 中若有一個數字 \(x\),\(x \bot n\),則 \(\gcd(x,n)=1\),
由更相減損術可得,\(\gcd(n,n-x)=1\),即 \((n-x)\bot n\),且 \((n-x)\in [1,n]\)。
\(n,n-x\) 的平均數為 $\frac{n}{2} $。
所以可知在 \([1,n]\) 中,與 \(n\) 互質的數字總成對存在,且這些數字平均數為 $\frac{n}{2} $。
又因為在 \([1,n]\) 中與 \(n\) 互質的數字個數為 \(\varphi(n)\),
所以 \(1 \sim n\) 中與 \(n\) 互質的數字和為 $\frac{n}{2} \varphi(n) $。
證畢.
- \(\varphi(x)\) 為積性函式,即 \(\forall a,b\) 且 \(a\bot b\), 都有 $ \varphi(ab)=\varphi(a)\varphi(b)$。
證明
設 \(a=\prod\limits^{x}_{i=1}p_i^{c_i},b=\prod\limits^{y}_{i=1}q_i^{d_i}\),且 $a \bot b $,則 \(\varphi(a)=a\times\prod\limits^{x}_{i=1}(1-\frac{1}{p_i}),\varphi(b)=b\times\prod\limits^{y}_{i=1}(1-\frac{1}{q_i})\)。
那麼 \(ab=\prod\limits^{x}_{i=1}p_i^{c_i}\times\prod\limits^{y}_{i=1}q_i^{d_i}\),則 \(\varphi(ab)=ab\times\prod\limits^{x}_{i=1}(1-\frac{1}{p_i})\times\prod\limits^{y}_{i=1}(1-\frac{1}{q_i})\)。
所以 \(\varphi(ab)=a\times b\times\prod\limits^{x}_{i=1}(1-\frac{1}{p_i})\times\prod\limits^{y}_{i=1}(1-\frac{1}{q_i})=\varphi(a)\varphi(b)\),即 \(\varphi(x)\) 為積性函式。
證畢.
- 當 \(n=p^k\),\(p\) 為質數,則 \(\varphi(n) = (p-1)*p^{k-1}\),且 \(\varphi(p)=p-1\)。
證明
\(1 \sim n\) 中與 \(n\) 不互質的數字均為 \(p\) 的倍數,而 \(1 \sim n\) 中 \(p\) 的倍數有 \(p^{k-1}\) 個,故 \(\varphi(n)=p^k-p^{k-1}=(p-1)*p^{k-1}\)。
證畢.
- 若 \(p\) 為質數,且 \(p\) 為 \(n\) 的約數,那麼有 \(\varphi(n*p)=\varphi(n)*p\)。
原因顯然。
另一種說法
若 \(p\) 為質數,\(p | n\) 且 \(p^2|n\),則 \(\varphi(n) = \varphi(\frac{n}{p}) * p\)。
- 若 \(p\) 為質數且 \(p\) 不為 \(n\) 的約數,那麼有 \(\varphi(n*p)=\varphi(n)*(p-1)\)。
證明
\(\gcd(n,p)=1\),即 \(n,p\) 互質,那麼 \(\varphi(n*p)=\varphi(n)*\varphi(p)=\varphi(n)*(p-1)\)。
證畢.
- \(\sum\limits^{}_{d|n} \varphi(d)=n。\)
證明
設有函式 \(f(n) = \sum\limits^{}_{d|n} \varphi(d)\),若有 \(n, m\) 互質,則 \(f(nm) = \sum\limits^{}_{d|nm} \varphi(d)=\sum\limits^{}_{x|n} \sum\limits^{}_{y|m} \varphi(xy)=\sum\limits^{}_{x|n} \varphi(x) * \sum\limits^{}_{y|m} \varphi(y)=f(n)f(m)\),即 \(f(n)\) 為積性函式。
對於單個質因子 \(p^m\),有 \(f(p^m)=\sum\limits^{}_{d|{p^m}} \varphi(d)=\varphi(1)+\varphi(p)+\varphi(p^2)+...+\varphi(p^m)\)。可知這是個等比數列求和再加一,結果為 \(p^m\)。
所以 \(f(n)=\prod\limits^{m}_{i=1} f(p_i^{c_i})=\prod\limits^{m}_{i=1} p_i^{c_i}=n\)。
證畢.
求尤拉函式值
- 求單個值 \(n\) 的尤拉函式值:
int phi(int n) {
int ans = n;
int t = sqrt(n);
for(int i=2; i<=t; ++i) {
if(n%i == 0)
ans = ans/i*(i-1);
while(n%i == 0) n /= i;
}
if(n > 1) ans = ans/n/(n-1);
return ans;
}
時間複雜度為 \(\Omicron(\sqrt{n})\)。
- 埃氏篩求 \(1 \sim n\) 的尤拉函式值:
void found_euler(int n) {
for(int i=1; i<=n; ++i) phi[i] = i;
for(int i=2; i<=n; ++i) {
if(phi[i] == i) { // i為質數
for(int j=i; j<=n; j+=i) // 給包含質因子i的數字,乘上 (1-1/i)
phi[j] = phi[j]/i*(i-1);
}
}
}
時間複雜度為 \(\Omicron(n \log n)\)。
- 線性篩求 \(1 \sim n\) 的尤拉函式值:
int v[maxn], p[maxn], phi[maxn];
void found_euler(int n) {
memset(v, 0, sizeof(v));
cnt = 0;
phi[1] = 1;
for(int i=2; i<=n; ++i) {
if(v[i]==0) {
v[i] = i;
p[++cnt] = i;
phi[i] = i-1; // i是質數
}
for(int j=1; j<=cnt; ++j) {
if(p[j]>v[i] || p[j]>n/i)
break;
v[i*p[j]] = p[j];
if(i%p[j] == 0) // i*p[j]是合數,要麼互質,要麼 p[j] 是 i的最小質因子(約數)
phi[i*p[j]] = phi[i] * p[j];
else phi[i*p[j]] = phi[i] * (p[j]-1);
}
}
}
時間複雜度為 \(\Omicron(n)\)。
同餘
定義
若整數 \(a, b\) 除以正整數 \(m\) 的餘數相等,則稱 \(a,b\) 模 \(m\) 同餘,記為 \(a \equiv b (mod m)\)。
同餘類與剩餘系
對於 \(\forall a \in [0,m-1]\),集合 \(\{a+km\}(k\in \Zeta)\) 的所有數 \(mod\) \(m\) 相等,餘數均為 \(a\)。
該集合稱為一個模 \(m\) 的同餘系,簡記為 \(\overline{a}\)。
模 \(m\) 的 \(m\) 個同餘類構成 \(m\) 的完全剩餘系。
\(1 \sim m\) 中有 \(\varphi(m)\) 個數字與 \(m\) 互質,這些數字代表的剩餘類構成 \(m\) 的簡化剩餘系。
簡化剩餘系關於模 \(m\) 乘法封閉,因為若小於等於 \(m\) 的正整數 \(a,b\) 與 \(m\) 互質,則 \(\gcd(ab,m)=1\)。由余數定義得 \(ab\) \(\text{mod}\) \(m\) 也與 \(m\) 互質,即也屬於 \(m\) 的簡化剩餘系。
費馬小定理
若 \(p\) 是質數,則對於任意整數 \(a\),有 \(a^p \equiv a(\bmod p)\)。
OiWiki Proof:
設一個質數為 \(p\),我們取一個不為 \(p\) 倍數的數 \(a\)。
構造一個序列:\(A=\{1,2,3\dots,p-1\}\),這個序列有著這樣一個性質:
證明:
又因為每一個 \(A_i\times a \pmod p\) 都是獨一無二的,且 \(A_i\times a \pmod p < p\)
得證(每一個 \(A_i\times a\) 都對應了一個 \(A_i\))
設 \(f=(p-1)!\), 則 \(f\equiv a\times A_1\times a\times A_2\times a \times A_3 \dots \times A_{p-1} \pmod p\)
證畢。
也可用歸納法證明:
顯然 \(1^p\equiv 1\pmod p\),假設 \(a^p\equiv a\pmod p\) 成立,那麼透過二項式定理有
因為 \(\binom{p}{k}=\frac{p(p-1)\cdots (p-k+1)}{k!}\) 對於 \(1\leq k\leq p-1\) 成立,在模 \(p\) 意義下 \(\binom{p}{1}\equiv \binom{p}{2}\equiv \cdots \equiv \binom{p}{p-1}\equiv 0\pmod p\),那麼 \((a+1)^p \equiv a^p +1\pmod p\),將 \(a^p\equiv a\pmod p\) 帶入得 \((a+1)^p\equiv a+1\pmod p\) 得證。
尤拉定理
若 \(a,n\) 為正整數且互質,則 \(a^{\varphi(n)} \equiv 1(\bmod n)\)。
OiWiki Proof:
實際上這個證明過程跟上文費馬小定理的證明過程是非常相似的:構造一個與 \(m\) 互質的數列,再進行操作。
設 \(r_1, r_2, \cdots, r_{\varphi(m)}\) 為模 \(m\) 意義下的一個簡化剩餘系,則 \(ar_1, ar_2, \cdots, ar_{\varphi(m)}\) 也為模 \(m\) 意義下的一個簡化剩餘系。所以 \(r_1r_2 \cdots r_{\varphi(m)} \equiv ar_1 \cdot ar_2 \cdots ar_{\varphi(m)} \equiv a^{\varphi(m)}r_1r_2 \cdots r_{\varphi(m)} \pmod{m}\),可約去 \(r_1r_2 \cdots r_{\varphi(m)}\),即得 \(a^{\varphi(m)} \equiv 1 \pmod{m}\)。
當 \(m\) 為素數時,由於 \(\varphi(m) = m - 1\),代入尤拉定理可立即得到費馬小定理。
尤拉定理推論
若正整數 \(a,n\) 互質,則對於任意正整數 \(b\),有 \(a^b \equiv a^{b \bmod \varphi(n)}(\bmod n)\)。
當 \(a,n\) 不一定互質時,且 \(b>\varphi(n)\),\(a^b \equiv a^{b \bmod \varphi(n)+\varphi(n)}(\bmod n)\)。
擴充套件尤拉定理
定義:
OiWiki Proof:
-
命題:\(a\) 的從 \(0\) 次,\(1\) 次到 \(b\) 次冪模 \(m\) 構成的序列中,存在 \(r\) 和 \(s\),使得前 \(r\) 個數(即從 \(a^0 \bmod m\) 到 \(a^{r-1} \bmod m\))互不相同,從第 \(r\) 個數開始,每 \(s\) 個數就迴圈一次。
證明:
-
由鴿巢定理易證。
我們把 \(r\) 稱為 \(a\) 冪次模 \(m\) 的迴圈起始點,\(s\) 稱為迴圈長度。(注意:\(r\) 可以為 \(0\))
用公式表述為:\(\forall i \ge r, a^i \equiv a^{i+s} \pmod{m}\)
-
-
命題:\(a\) 為素數的情況,該式成立。
證明:
-
若模 \(m\) 不能被 \(a\) 整除,而因為 \(a\) 是一個素數,那麼 \(\gcd(a, m) = 1\) 成立,根據尤拉定理,容易證明該式成立。
-
若模 \(m\) 能被 \(a\) 整除,那麼存在 \(r\) 和 \(m'\) 使得 \(m = a^r m'\),且 \(\gcd(a, m')=1\) 成立。所以根據尤拉定理有 \(a^{\varphi(m')} \equiv 1 \pmod{m'}\)。
又由於 \(\gcd(a^r, m')=1\),所以根據尤拉函式的求值規則,容易得到:\(\varphi(m) = \varphi(m') \times (a-1)a^{r-1}\),即我們有:\(\varphi(m') \mid \varphi(m)\)。
所以 \(a^{\varphi(m')} \equiv 1 \pmod {m'}, \varphi(m') \mid \varphi(m) \implies a^{\varphi(m)} \equiv 1 \pmod {m'}\),即 \(a^{\varphi(m)}=km'+1\),兩邊同時乘以 \(a^r\),得 \(a^{r+\varphi(m)} = km + a^r\)(因為 \(m = a^r m'\))
所以對於 \(m\) 中素因子 \(a\) 的次數 \(r\) 滿足:\(a^r \equiv a^{r+\varphi(m)} \pmod m\)。我們可以簡單變換形式,得到 推論:
\[b > r \implies a^b \equiv a^{r + ((b-r) \bmod \varphi(m))} \pmod {m} \]又由於 \(m = a^r m'\),所以 \(\varphi(m) = \varphi(a^r) \varphi(m') \ge \varphi(a^r)=a^{r-1}(a-1) \ge r\)(tips:\(a\) 是素數,最小是 \(2\),而 \(r \ge 1\))。
所以因為 \(\varphi(m) \ge r\),故有:
\[a^r \equiv a^{r+\varphi(m)} \equiv a^{r \bmod \varphi(m)+\varphi(m)} \pmod m \]所以
\[\begin{aligned} a^b &\equiv a^{r+(b-r) \bmod \varphi(m)} \\ &\equiv a^{r \bmod \varphi(m) + \varphi(m) + (b-r) \bmod \varphi(m)} \\ &\equiv a^{\varphi(m) + b \bmod \varphi(m)} \end{aligned} \pmod m \]即 \(a^b\equiv a^{b \bmod \varphi(m)+\varphi(m)}\pmod m\)。
-
-
命題:\(a\) 為素數的冪的情況,該式成立。
證明:
-
不妨令 \(a = p^k\),是否依然有 \(\forall r, a^{r} \equiv a^{r+\varphi(m)} \pmod m\)?
答案是肯定的,由命題 1 可知存在 \(s\) 使得 \(a^s\equiv 1 \pmod m\),所以 \(p^{\mathrm{lcm}(s,k)} \equiv 1 \pmod {m}\),所以令 \(s'=\frac{s}{\gcd(s,k)}\) 時,我們能有 \(p^{s'k} \equiv 1 \pmod {m}\)。
此時有關係:\(s' \mid s\) 且 \(s \mid \varphi(m)\),且 \(r'= \lceil \frac{r}{k}\rceil \le r \le \varphi(m)\),由 \(r',s'\) 與 \(\varphi(m)\) 的關係,依然可以得到 \(a^b\equiv a^{b \bmod \varphi(m)+\varphi(m)}\pmod m\)。
-
-
命題:\(a\) 為合數的情況,該式成立。
證明:
-
只證 \(a\) 拆成兩個素數的冪的情況,大於兩個的用數學歸納法可證。
設 \(a=a_1a_2\),其中 \(a_i=p_i^{k_i}\),而 \(a_i\) 的迴圈長度為 \(s_i\);
則 \(s \mid \operatorname{lcm}(s_1,s_2)\),由於 \(s_1 \mid \varphi(m),s_2 \mid \varphi(m)\),那麼 \(\operatorname{lcm}(s_1,s_2) \mid \varphi(m)\),所以 \(s \mid \varphi(m)\),\(r=\max(\lceil \frac{r_i}{k_i} \rceil) \le \max(r_i) \le \varphi(m)\);
由 \(r,s\) 與 \(\varphi(m)\) 的關係,依然可以得到 \(a^b \equiv a^{b \bmod \varphi(m)+\varphi(m)}\pmod m\)。
證畢。
-
以上為形式證明。直觀理解如下。
需要知道的是,在 \(\pmod m\) 的條件下,\(a^b \bmod m\) 的取值範圍一定在 \([0, m)\),而 \(a^i \bmod m = (a^{i-1} \bmod m) \times a \bmod m\),那麼對於任意一個數 \(a\),那麼很容易就能知道它的 後繼,在有限的空間內這一定會形成一個迴圈。
在擴充套件尤拉定理中,迴圈分為純迴圈和混迴圈。其中純迴圈中不存在節點有兩個前驅,而混迴圈則反之。而 \(a^i \mod n\) 形成的序列可以是一個混迴圈,那麼只需要知道迴圈節的長度,和前面那一小段未進入迴圈節的長度,就可以根據這個性質來進行降冪了。
值得注意的是,無論是費馬小定理,還是(擴充套件)尤拉定理,一個很重要的應用就是降冪,從而將不可能的表示式化為可能。
擴充套件歐幾里得演算法(exgcd)
裴蜀定理
在數論中,裴蜀定理是一個關於最大公約數(或最大公約式)的定理 。
裴蜀定理說明了對任何整數 a、b和它們的最大公約數 d ,關於未知數 x以及 y 的線性的丟番圖方程(稱為裴蜀等式)。
對於 \(\forall a,b \in \Zeta\),存在一對 \(x,y \in \Zeta\),滿足 \(ax+by=\gcd(a,b)\)。
Proof:
歐幾里得演算法最後一步時,\(b=0\),顯然有一對 \(x=1,y=0\),使 \(a*1+0*0=\gcd(a,0)\)。
如果 \(b>0\),則 \(\gcd(a,b)=\gcd(b, a \bmod b)\)。假設存在一對 \(x,y \in \Zeta\),滿足 \(b*x+(a \bmod b)*y=\gcd(b, a\bmod b)\),因為 \(bx+(a \bmod b)y=bx+(a-b\lfloor\frac{a}{b}\rfloor)y=ay+b(x-\lfloor\frac{a}{b}\rfloor)y\),所以我們令 \(x`=y,y`=x-\lfloor\frac{a}{b}\rfloor y\),得到 \(ax`+by`=\gcd(a,b)\)。
對於歐幾里得演算法遞回應用數學歸納,可知裴蜀定理成立。
裴蜀定理是按照歐幾里得演算法思想證明的,且上述證明給出 \(x,y\) 計算方法。這種方法被稱為 擴充套件歐幾里得演算法。
ll exgcd(ll a, ll b, ll &x, ll &y) {
if (b == 0) {
x = 1;
y = 0;
return a;
}
ll res = exgcd(b, a % b, x, y);
ll z = x;
x = y;
y = z - (a / b) * y;
return res;
}
上述 \(code\) 實現求出方程 \(ax+by=\gcd(a,b)\) 的一組特解,並返回 \(\gcd(a,b)\)。
對於更一般的方程 \(ax+by=c\),有解當且僅當 \(\gcd(a,b)\) 整除 \(c\)。
先求出 \(ax+by=\gcd\) 的一組特解,同時乘 \(\frac{c}{d}\),就得到此方程的一個特解。
實際上,其通解可以表示為:
其中 \(k \in \Zeta\)。
乘法逆元
\(b,m\in\Zeta\),\(b\) 整除 \(a\),那麼存在一個 \(x\in\Zeta\),使 \(\frac{a}{b} \equiv a*x(\bmod m)\)。稱 \(x\) 為 \(b\) 的模 \(m\) 乘法逆元,記作 \(b^{-1}\)。
乘法逆元可以視情況透過費馬小定理或者求解同餘方程得到。
ll inv = ksm(p[i] - 1, mod - 2);
或者線性求出 \(1 \sim n\) 所有逆元。
f[0] = 1;
for(int i=1; i<=n; ++i) //求字首積,即 i!
f[i] = (LL)(f[i-1]*i) % p;
g[n] = quick_pow(f[n], p-2, p); // 求 n!的逆元
for(int i=n-1; i>=1; --i) // 遞推出所有的階乘的逆元
g[i] = (LL)(g[i+1]*(i+1)) % p;
for(int i=1; i<=n; ++i) { // 求出 i 的逆元
h[i] = (LL)(g[i]*f[i-1]) % p;
printf("%lld\n", h[i]);
}
線性同餘方程
給定 \(a,b,m\in\Zeta\),求 \(x\in \Zeta\),\(a*x\equiv b(\bmod m)\),或給出無解。
此時未知數指數為 \(1\),所以我們稱這種同餘方程為一次同餘方程,或者為線性同餘方程。
原方程可以寫成 \(a*x+m*y=b\),那麼據裴蜀定理,有解當且僅當 \(\gcd(a,m)\) 整除 \(b\)。
有解時先用 \(exgcd\) 求出 \(a*x_0+b*y_0=\gcd(a,m)\) 的 \(x,y \in \Zeta\)。\(x=x_0*\frac{b}{\gcd(a,m)}\) 為原方程一個解。
通解為所有 \(\bmod \frac{m}{\gcd(a,m)}\) 與 \(x\) 同餘的整數。
中國剩餘定理(CRT)
一共 \(n\) 個線性同餘方程組,求解。
(其中 \(n_1, n_2, \cdots, n_k\) 兩兩互質)
-
計算所有模數的積 \(n\);
-
對於第 \(i\) 個方程:
- 計算 \(m_i=\frac{n}{n_i}\);
- 計算 \(m_i\) 在模 \(n_i\) 意義下的逆元 \(m_i^{-1}\);
- 計算 \(c_i=m_im_i^{-1}\)(不要對 \(n_i\) 取模)。
-
方程組在模 \(n\) 意義下的唯一解為:\(x=\sum_{i=1}^k a_ic_i \pmod n\)。
Proof:
因為 \(m_i=\frac{n}{n_i}\),是除了 \(n_i\) 以外所有模數的倍數,所以 \(\forall k \not= i,a_i m_i m_i^{-1} \equiv 0(\bmod n_k)\)。又因為 \(a_i m_i m_i^{-1} \equiv a_i(\bmod n_i)\),所以代入 \(x=\sum_{i=1}^k a_i c_i \pmod n\),原方程組成立。
證畢。
如果模數不互質,此時我們可以使用 擴充套件中國剩餘定理(exCRT)。
exCRT Solutions。