Bài 26: Số Học Nâng Cao - Euler Totient, Modular Arithmetic & CRT¶
Tác giả: FPTOJ Team
Nội dung tham khảo từ: VNOI Wiki - Số học, HackerEarth Number Theory Series, CP-Algorithms
1. Euler Totient - Đếm số nguyên tố cùng nhau¶
Bản chất vấn đề¶
Cho số nguyên dương \(N\), cần đếm số nguyên dương \(x \in [1, N]\) sao cho \(\gcd(x, N) = 1\). Gọi kết quả là \(\varphi(N)\) (Euler's Totient).
| \(N\) | Các số nguyên tố cùng nhau với \(N\) | \(\varphi(N)\) |
|---|---|---|
| 1 | \(\{1\}\) | 1 |
| 7 | \(\{1, 2, 3, 4, 5, 6\}\) | 6 |
| 9 | \(\{1, 2, 4, 5, 7, 8\}\) | 6 |
| 12 | \(\{1, 5, 7, 11\}\) | 4 |
Tư duy cốt lõi¶
Cho \(N = p_1^{a_1} \times p_2^{a_2} \times \cdots \times p_k^{a_k}\) (phân tích thừa số nguyên tố), trong đó \(p_i\) là các thừa số nguyên tố phân biệt của \(N\), \(a_i\) là số mũ tương ứng. Công thức:
(\(\prod\) là ký hiệu tích — nhân tất cả các phần tử)
Chứng minh trực giác: Dùng nguyên lý bao hàm - loại trừ (inclusion-exclusion). Trong \(N\) số từ \(1\) đến \(N\), loại bỏ bội của \(p_1, p_2, \ldots\), rồi cộng lại phần bị trừ trùng.
Tính chất quan trọng:
| Tính chất | Công thức | Ý nghĩa |
|---|---|---|
| Số nguyên tố | \(\varphi(p) = p - 1\) | Mọi số \(< p\) đều nguyên tố cùng nhau với \(p\) |
| Lũy thừa nguyên tố | \(\varphi(p^k) = p^k - p^{k-1} = p^{k-1}(p - 1)\) | Chỉ loại bội của \(p\) |
| Nhân tính | \(\varphi(m \times n) = \varphi(m) \times \varphi(n)\) nếu \(\gcd(m, n) = 1\) | Chia nhỏ bài toán |
| Tổng chia hết | \(\sum_{d \mid N} \varphi(d) = N\) (với \(d \mid N\) nghĩa là \(d\) chia hết \(N\)) | Dùng trong nhiều bài đếm |
Phân tích tính đúng đắn¶
Với \(N = 12 = 2^2 \times 3\):
Kiểm tra: \(\{1, 5, 7, 11\}\) - đúng 4 số, thỏa \(\gcd(x, 12) = 1\).
Đánh giá độ phức tạp¶
| Thuật toán | Độ phức tạp | Ghi chú |
|---|---|---|
| Tính \(\varphi(n)\) đơn lẻ | \(O(\sqrt{n})\) | Phân tích thử từ 2 đến \(\sqrt{n}\) |
| Sàng Euler (tính \(\varphi\) cho \(1 \ldots N\)) | \(O(N \log \log N)\) | Tương tự sàng Eratosthenes |
2. Modular Arithmetic & Tổ hợp modulo¶
Bản chất vấn đề¶
Khi tính toán với số rất lớn, ta lấy dư cho một số nguyên tố \(p\) (thường \(p = 10^9 + 7\)). Phép chia modulo không trực tiếp được mà phải dùng modular inverse.
Tư duy cốt lõi¶
Các phép tính modulo cơ bản:
| Phép tính | Công thức | Lưu ý |
|---|---|---|
| Cộng | \((a + b) \bmod p = ((a \bmod p) + (b \bmod p)) \bmod p\) | Trực tiếp |
| Trừ | \((a - b) \bmod p = ((a \bmod p) - (b \bmod p) + p) \bmod p\) | Cộng \(p\) để tránh âm |
| Nhân | \((a \times b) \bmod p = ((a \bmod p) \times (b \bmod p)) \bmod p\) | Trực tiếp |
| Chia | \((a / b) \bmod p = (a \times b^{p-2}) \bmod p\) | Chỉ đúng khi \(p\) nguyên tố |
Phép chia modulo thực chất là nhân với modular inverse. Modular inverse của \(b\) modulo \(p\) là số \(b^{-1}\) sao cho \(b \times b^{-1} \equiv 1 \pmod{p}\).
Khi \(p\) nguyên tố, dùng Fermat's Little Theorem: \(b^{-1} \equiv b^{p-2} \pmod{p}\).
Công thức tổ hợp:
Với \(\text{inv\_fact}[i]\) là modular inverse của \(i!\).
Phân tích tính đúng đắn¶
Tính \(C(5, 2) \bmod (10^9 + 7)\):
- \(\text{fact}[5] = 120\), \(\text{fact}[2] = 2\), \(\text{fact}[3] = 6\)
- \(\text{inv\_fact}[2] = 2^{10^9+5} \bmod (10^9+7) = 500000004\)
- \(\text{inv\_fact}[3] = 6^{10^9+5} \bmod (10^9+7) = 166666668\)
- \(C(5,2) = 120 \times 500000004 \times 166666668 \bmod (10^9+7) = 10\)
Kiểm tra: \(C(5,2) = 10\) - đúng.
Đánh giá độ phức tạp¶
| Thuật toán | Độ phức tạp | Ghi chú |
|---|---|---|
| Lũy thừa modulo \(a^b \bmod p\) | \(O(\log b)\) | Binary exponentiation |
| Xây dựng factorial + inverse | \(O(N)\) | Precompute một lần |
| Truy vấn \(C(n,k)\) | \(O(1)\) | Sau khi precompute |
3. Lucas Theorem¶
Bản chất vấn đề¶
Khi \(n\) rất lớn (ví dụ \(10^{18}\)) nhưng \(p\) nhỏ (ví dụ \(10^6\)), ta không thể tính \(\text{fact}[n]\) trực tiếp vì \(n > p\) khiến \(\text{fact}[n] \equiv 0 \pmod{p}\). Cần một phương pháp chia nhỏ bài toán.
Tư duy cốt lõi¶
Biểu diễn \(n\) và \(k\) ở hệ cơ số \(p\):
Thì:
Lưu ý: Nếu bất kỳ \(k_i > n_i\) thì \(C(n_i, k_i) = 0\), toàn bộ tích bằng 0.
Ví dụ: Tính \(C(10, 3) \bmod 3\).
| Chữ số hệ cơ số 3 | \(n_i\) | \(k_i\) | \(C(n_i, k_i) \bmod 3\) |
|---|---|---|---|
| \(i = 0\) | 1 | 0 | 1 |
| \(i = 1\) | 0 | 1 | 0 |
\(C(10, 3) \bmod 3 = 1 \times 0 = 0\).
Phân tích tính đúng đắn¶
Lucas Theorem đúng vì \(C(n, k)\) trong trường \(\mathbb{Z}_p\) có thể phân tích theo từng chữ số hệ cơ số \(p\), tương tự cách khai triển đa thức \((1 + x)^n \bmod p\).
Điều kiện áp dụng: \(p\) phải là số nguyên tố.
Đánh giá độ phức tạp¶
| Thuật toán | Độ phức tạp | Ghi chú |
|---|---|---|
| Lucas Theorem | \(O(\log_p n \cdot p)\) | \(\log_p n\) chữ số, mỗi chữ số tính \(C(n_i, k_i)\) |
| \(C(n_i, k_i)\) trực tiếp | \(O(k_i)\) | Vì \(n_i, k_i < p\) |
4. Chinese Remainder Theorem (CRT)¶
Bản chất vấn đề¶
Cho các cặp \((a_1, m_1), (a_2, m_2), \ldots, (a_k, m_k)\) với \(m_i\) đôi một nguyên tố cùng nhau, tìm \(x\) sao cho:
Nghiệm duy nhất modulo \(M = m_1 \times m_2 \times \cdots \times m_k\).
Tư duy cốt lõi¶
Trường hợp 2 phương trình:
Cho \(x \equiv a_1 \pmod{m_1}\) và \(x \equiv a_2 \pmod{m_2}\) với \(\gcd(m_1, m_2) = 1\):
- \(M = m_1 \times m_2\)
- \(M_1 = M / m_1\), \(M_2 = M / m_2\)
- \(y_1 = M_1^{-1} \bmod m_1\), \(y_2 = M_2^{-1} \bmod m_2\)
- \(x = (a_1 \times M_1 \times y_1 + a_2 \times M_2 \times y_2) \bmod M\)
Mở rộng cho nhiều phương trình: Gộp từng cặp một cách tuần tự.
Phân tích tính đúng đắn¶
Ví dụ:
| Phương trình | \(a_i\) | \(m_i\) |
|---|---|---|
| \(x \equiv 2 \pmod{3}\) | 2 | 3 |
| \(x \equiv 3 \pmod{5}\) | 3 | 5 |
| \(x \equiv 2 \pmod{7}\) | 2 | 7 |
- \(M = 3 \times 5 \times 7 = 105\)
- Gộp \((2, 3)\) và \((3, 5)\): \(x = 8 \pmod{15}\)
- Gộp \((8, 15)\) và \((2, 7)\): \(x = 23 \pmod{105}\)
Kiểm tra: \(23 \bmod 3 = 2\), \(23 \bmod 5 = 3\), \(23 \bmod 7 = 2\) - đúng.
Đánh giá độ phức tạp¶
| Thuật toán | Độ phức tạp | Ghi chú |
|---|---|---|
| CRT 2 phương trình | \(O(\log m)\) | Extended GCD |
| CRT \(k\) phương trình | \(O(k \log m)\) | Gộp tuần tự |
5. Hàm Möbius¶
Bản chất vấn đề¶
Hàm Möbius \(\mu(n)\) là công cụ đếm mạnh mẽ, xuất hiện trong phép đảo ngược Möbius (Möbius inversion) và nhiều bài toán đếm cặp số nguyên tố cùng nhau.
Tư duy cốt lõi¶
Định nghĩa:
| Điều kiện | \(\mu(n)\) | Ví dụ |
|---|---|---|
| \(n = 1\) | \(1\) | \(\mu(1) = 1\) |
| \(n\) có thừa số nguyên tố bậc \(\geq 2\) | \(0\) | \(\mu(4) = 0\), \(\mu(12) = 0\) |
| \(n = p_1 p_2 \cdots p_k\) (tích của \(k\) nguyên tố phân biệt) | \((-1)^k\) | \(\mu(6) = 1\), \(\mu(30) = -1\) |
Tính chất cốt lõi (hàm nghịch đảo của hàm hằng số 1 theo convolution Dirichlet):
Möbius Inversion: Nếu \(f(n) = \sum_{d \mid n} g(d)\) thì \(g(n) = \sum_{d \mid n} \mu(d) \cdot f(n/d)\).
Phân tích tính đúng đắn¶
Kiểm tra \(\sum_{d \mid 6} \mu(d)\):
| \(d\) | \(\mu(d)\) |
|---|---|
| 1 | 1 |
| 2 | -1 |
| 3 | -1 |
| 6 | 1 |
Tổng: \(1 + (-1) + (-1) + 1 = 0 = [6 = 1]\) - đúng.
Đánh giá độ phức tạp¶
| Thuật toán | Độ phức tạp | Ghi chú |
|---|---|---|
| Tính \(\mu(n)\) đơn lẻ | \(O(\sqrt{n})\) | Phân tích thử |
| Sàng Möbius (tính \(\mu\) cho \(1 \ldots N\)) | \(O(N \log \log N)\) | Linear sieve |
6. Pollard's Rho - Phân tích thừa số lớn¶
Bản chất vấn đề¶
Phân tích thừa số nguyên tố của số \(n\) rất lớn (lên \(10^{18}\)). Trial division \(O(\sqrt{n})\) quá chậm. Cần thuật toán nhanh hơn.
Tư duy cốt lõi¶
Sử dụng hàm \(f(x) = (x^2 + c) \bmod n\) để tạo dãy số. Dùng Floyd's cycle detection (hare-tortoise) để tìm \(\gcd(|x_i - x_j|, n) \neq 1\), tức là tìm được ước không tầm thường.
Hai thành phần chính:
| Thành phần | Vai trò |
|---|---|
| Miller-Rabin | Kiểm tra nguyên tố - \(O(k \log^2 n)\) |
| Pollard's Rho | Tìm ước không tầm thường - \(O(n^{1/4})\) trung bình |
Miller-Rabin: Viết \(n - 1 = 2^r \cdot d\), kiểm tra \(a^d \bmod n\) với nhiều cơ sở \(a\). Đủ 12 cơ bộ \(\{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37\}\) cho \(n < 2^{64}\).
Phân tích tính đúng đắn¶
Pollard's Rho dựa trên Birthday Paradox: dãy \(\{f(f(\cdots f(x_0)\cdots))\} \bmod n\) sẽ chu kỳ sau \(O(\sqrt{n})\) bước. Khi phát hiện chu kỳ, \(\gcd(|x - y|, n)\) có xác suất cao là ước không tầm thường của \(n\).
Đánh giá độ phức tạp¶
| Thuật toán | Độ phức tạp | Ghi chú |
|---|---|---|
| Miller-Rabin | \(O(k \log^2 n)\) | \(k\) là số cơ sở |
| Pollard's Rho | \(O(n^{1/4})\) trung bình | Có thể chậm hơn trong worst case |
| Phân tích thừa số đầy đủ | \(O(n^{1/4} \log n)\) | Gọi đệ quy Pollard's Rho |
7. Ứng dụng thực tế¶
7.1 Đếm số cặp nguyên tố cùng nhau¶
Bài toán: Cho mảng \(A[1..N]\), đếm số cặp \((i, j)\) với \(i < j\) sao cho \(\gcd(A[i], A[j]) = 1\).
Cách làm: Dùng hàm Möbius và nguyên lý bao hàm - loại trừ:
Với \(\text{cnt}[d]\) là số phần tử trong mảng chia hết cho \(d\).
7.2 Euler's Theorem cho Modular Exponentiation với số mũ lớn¶
Khi tính \(a^b \bmod n\) với \(b\) rất lớn (ví dụ \(b = 10^{10^{18}}\)), dùng Euler's Theorem để rút gọn:
Khi \(\gcd(a, n) \neq 1\) và \(b \geq \varphi(n)\):
7.3 Möbius Inversion - Đếm cặp GCD¶
Bài toán: Đếm số cặp \((i, j)\) với \(1 \leq i \leq N\), \(1 \leq j \leq M\) sao cho \(\gcd(i, j) = 1\).
Công thức: \(\sum_{d=1}^{\min(N,M)} \mu(d) \times \lfloor N/d \rfloor \times \lfloor M/d \rfloor\) (với \(\lfloor x \rfloor\) là phần nguyên — làm tròn xuống — của \(x\))
7.4 RSA Cryptography (tóm tắt)¶
RSA sử dụng Euler's Totient:
| Bước | Thao tác | Công thức |
|---|---|---|
| 1 | Chọn 2 số nguyên tố lớn \(p\), \(q\) | \(n = p \times q\), \(\varphi(n) = (p-1)(q-1)\) |
| 2 | Chọn \(e\) sao cho \(\gcd(e, \varphi(n)) = 1\) | Khóa công khai: \((e, n)\) |
| 3 | Tính \(d = e^{-1} \bmod \varphi(n)\) | Khóa bí mật: \((d, n)\) |
| 4 | Mã hóa | \(c = m^e \bmod n\) |
| 5 | Giải mã | \(m = c^d \bmod n\) |
8. Lưu ý & Cạm bẫy¶
8.1 Modular Arithmetic Pitfalls¶
| Bẫy | Sai | Đúng |
|---|---|---|
| Chia modulo khi modulus không nguyên tố | \(a / b \bmod m = a \times b^{m-2} \bmod m\) | Dùng Extended GCD, yêu cầu \(\gcd(b, m) = 1\) |
| Trừ ra số âm | result = (a - b) % MOD |
result = ((a - b) % MOD + MOD) % MOD |
| Overflow khi nhân | a * b % MOD khi \(a, b > 10^9\) |
(__int128)a * b % MOD |
8.2 Lucas Theorem - Điều kiện áp dụng¶
- Chỉ áp dụng khi \(p\) là số nguyên tố. Nếu \(p\) không nguyên tố, Lucas theorem không đúng.
- Khi \(p\) nhỏ (\(\leq 10^6\)) và \(n\) rất lớn (\(10^{18}\)).
- Nếu \(p\) lớn (ví dụ \(10^9 + 7\)), Lucas theorem không hữu ích vì \(n < p\) trong hầu hết bài toán.
8.3 Xử lý giai thừa lớn¶
Khi nào \(\text{fact}[n]\) không tính được trực tiếp? Khi \(n > \text{MOD}\) (\(10^9 + 7\)). Khi đó \(\text{fact}[n] \equiv 0 \pmod{\text{MOD}}\) vì \(\text{MOD} \mid n!\).
Cách xử lý:
| Phương pháp | Khi nào dùng |
|---|---|
| Lucas Theorem | \(\text{MOD}\) là số nguyên tố |
| Phân tích thừa số nguyên tố của \(\text{MOD}\) | \(\text{MOD}\) không nguyên tố |
| \(C(n,k) \bmod p^e\) (Granville's generalization) | Trường hợp tổng quát |
8.4 Euler's Theorem vs Fermat's Little Theorem¶
| Định lý | Công thức | Điều kiện |
|---|---|---|
| Fermat | \(a^{p-1} \equiv 1 \pmod{p}\) | \(p\) nguyên tố, \(\gcd(a, p) = 1\) |
| Euler | \(a^{\varphi(n)} \equiv 1 \pmod{n}\) | \(\gcd(a, n) = 1\) |
Fermat là trường hợp đặc biệt của Euler vì \(\varphi(p) = p - 1\).
Khi tính \(a^b \bmod n\):
- Nếu \(\gcd(a, n) = 1\): dùng Euler, \(a^b \equiv a^{b \bmod \varphi(n)} \pmod{n}\)
- Nếu \(\gcd(a, n) \neq 1\): dùng kỹ thuật tách thừa số, \(a^b \equiv a^{b \bmod \varphi(n) + \varphi(n)} \pmod{n}\) khi \(b \geq \varphi(n)\)
8.5 Các bẫy thường gặp khác¶
| Bẫy | Giải pháp |
|---|---|
Quên mod ở mỗi bước tính |
Luôn % MOD sau mỗi phép nhân/cộng |
Dùng MOD = 1e9+7 nhưng quên nó là số nguyên tố |
Kiểm tra tính nguyên tố của modulus trước |
Tính inv_fact sai thứ tự |
Phải tính từ \(n\) xuống \(0\) |
| Lucas trả về 0 nhưng thực tế \(C(n,k) \neq 0\) | Kiểm tra \(k_i > n_i\) ở mỗi chữ số |
| CRT cho modulus không nguyên tố cùng nhau | Dùng CRT tổng quát (với GCD chung) |
9. Bài tập luyện tập¶
9.1 Euler Totient & Modular Arithmetic¶
| Bài | Nền tảng | Độ khó | Chủ đề |
|---|---|---|---|
| SPOJ - ETF | SPOJ | ⭐⭐ | Euler Totient đơn lẻ |
| SPOJ - GCDEX | SPOJ | ⭐⭐⭐ | GCD + Euler Totient |
| CSES - Exponentiation | CSES | ⭐⭐ | Lũy thừa modulo |
| CSES - Exponentiation II | CSES | ⭐⭐⭐ | Euler's theorem |
| CSES - Binomial Coefficients | CSES | ⭐⭐ | Tổ hợp modulo |
| SPOJ - NCNK | SPOJ | ⭐⭐ | Tổ hợp lớn |
9.2 CRT & Lucas¶
| Bài | Nền tảng | Độ khó | Chủ đề |
|---|---|---|---|
| CF - Strange Housing | CF | ⭐⭐⭐ | CRT cơ bản |
| SPOJ - Chinese Remainder Theorem | SPOJ | ⭐⭐ | CRT trực tiếp |
| CF - Little Pony and Harmony Chest | CF | ⭐⭐⭐⭐ | Tổ hợp + bitmask |
9.3 Möbius & Đếm cặp¶
| Bài | Nền tảng | Độ khó | Chủ đề |
|---|---|---|---|
| CF - GCD Table | CF | ⭐⭐⭐ | GCD + tư duy |
| SPOJ - VLATTICE | SPOJ | ⭐⭐⭐ | Möbius 3D |
| CF - Neko and Aki's Prank | CF | ⭐⭐⭐ | Euler + tổ hợp |
| CSES - Counting Coprime Pairs | CSES | ⭐⭐⭐ | Möbius đếm cặp |
9.4 Pollard's Rho & Factorization¶
| Bài | Nền tảng | Độ khó | Chủ đề |
|---|---|---|---|
| SPOJ - FACT0 | SPOJ | ⭐⭐ | Phân tích thừa số |
| SPOJ - FACT1 | SPOJ | ⭐⭐⭐ | Phân tích số lớn |
| CF - Almost Everywhere Zero | CF | ⭐⭐⭐ | Phân tích + đếm |
9.5 Tổng hợp & Nâng cao¶
| Bài | Nền tảng | Độ khó | Chủ đề |
|---|---|---|---|
| CF - Yet Another Number Theory Problem | CF | ⭐⭐⭐ | Tổng hợp số học |
| CSES - NIM Game I | CSES | ⭐⭐ | Game theory + GCD |
| SPOJ - GCDEX2 | SPOJ | ⭐⭐⭐⭐ | GCD nâng cao |
| LeetCode - Count Primes | LeetCode | ⭐⭐ | Đếm số nguyên tố |
| LeetCode - Ugly Number II | LeetCode | ⭐⭐ | Số nguyên tố + DP |
| VNOJ - Euler Totient (etf) | VNOJ | ⭐⭐ | Phi hàm Euler |
| VNOJ - Tìm số (findnum) | VNOJ | ⭐⭐ | Số học |
| VNOJ - Số phong phú (nkabd) | VNOJ | ⭐⭐ | Ước số |
Bài viết liên quan¶
- Bài 11: Lũy thừa nhị phân & Sàng nguyên tố
- Bài 18: Euclid & Modular Inverse
- Bài 19: Tổ hợp & Xác suất
Tài liệu tham khảo¶
- HackerEarth - Number Theory 1-7
- VNOI Wiki - Số học
- CP-Algorithms - Euler Function
- CP-Algorithms - Modular Inverse
- CP-Algorithms - Chinese Remainder Theorem
- CP-Algorithms - Möbius Function
- CP-Algorithms - Pollard's Rho
- GeeksforGeeks - Euler's Totient Function