Bài 56: Sàng Nâng Cao & Hàm Ước¶
Tác giả: FPTOJ Team
Nội dung tham khảo từ: CP-Algorithms, VNOI Wiki
1. Sàng Smallest Prime Factor (SPF)¶
1.1 Tại sao cần sàng SPF?¶
Bài 11 đã giới thiệu sàng Eratosthenes để kiểm tra nguyên tố. Nhưng trong thi đấu, ta thường cần phân tích thừa số nguyên tố của nhiều số khác nhau. Phân tích trial division mất \(O(\sqrt{n})\) cho mỗi số → quá chậm nếu cần phân tích \(10^6\) số.
Sàng SPF cho phép phân tích bất kỳ số \(n \leq N\) thành các thừa số nguyên tố trong \(O(\log n)\).
1.2 Ý tưởng¶
Với mỗi số \(n\), lưu ước nguyên tố nhỏ nhất của nó. Khi cần phân tích \(n\), ta chỉ cần chia liên tục cho SPF:
1.3 Cài đặt¶
Độ phức tạp: Xây dựng sàng \(O(N \log \log N)\), mỗi phân tích \(O(\log n)\).
2. Sàng Tuyến Tính (Linear Sieve / Euler Sieve)¶
2.1 Vấn đề với sàng Eratosthenes¶
Sàng Eratosthenes đánh dấu bội của mỗi nguyên tố → một số hợp bị đánh dấu nhiều lần (ví dụ 12 bị đánh dấu bởi 2, 3). Độ phức tạp thực tế là \(O(N \log \log N)\), không phải \(O(N)\).
2.2 Ý tưởng sàng tuyến tính¶
Duyệt mỗi số \(i\) từ 2 đến \(N\). Với mỗi \(i\), duyệt các nguyên tố \(p\) trong danh sách và đánh dấu \(i \times p\). Dừng ngay khi \(p \mid i\).
Tại sao dừng? Đảm bảo mỗi số hợp chỉ bị đánh dấu đúng một lần bởi ước nguyên tố nhỏ nhất của nó.
2.3 Cài đặt¶
Độ phức tạp: \(O(N)\) - mỗi số hợp chỉ bị đánh dấu đúng một lần.
2.4 Sàng tuyến tính tính hàm nhân tính¶
Ưu điểm lớn nhất: có thể tính đồng thời nhiều hàm nhân tính (Euler φ, d(n), σ(n), ...) trong \(O(N)\).
3. Hàm Đếm Ước d(n)¶
3.1 Định nghĩa¶
\(d(n)\) = số ước dương của \(n\).
3.2 Công thức¶
Cho \(n = p_1^{a_1} \times p_2^{a_2} \times \cdots \times p_k^{a_k}\), thì:
Ví dụ: \(36 = 2^2 \times 3^2\) → \(d(36) = (2+1)(2+1) = 9\) ✓
3.3 Tính chất nhân tính¶
\(d(m \times n) = d(m) \times d(n)\) nếu \(\gcd(m, n) = 1\).
Đây là hàm nhân tính, nên có thể tính bằng sàng:
3.4 Đếm ước bằng phân tích thừa số - O(√n)¶
Khi chỉ cần tính \(d(n)\) cho một số đơn lẻ:
4. Tổng Ước σ(n)¶
4.1 Định nghĩa¶
\(\sigma(n)\) = tổng tất cả ước dương của \(n\).
4.2 Công thức¶
Cho \(n = p_1^{a_1} \times p_2^{a_2} \times \cdots \times p_k^{a_k}\) (với \(p_i\) là các thừa số nguyên tố phân biệt, \(a_i\) là số mũ), thì:
(Trong đó \(\prod\) là ký hiệu tích — nhân tất cả các vế từ \(i=1\) đến \(k\).)
Ví dụ: \(12 = 2^2 \times 3^1\) → \(\sigma(12) = \frac{2^3 - 1}{2 - 1} \times \frac{3^2 - 1}{3 - 1} = 7 \times 4 = 28\) ✓
4.3 Tính bằng sàng - O(N log N)¶
4.4 Tổng ước bằng phân tích thừa số¶
5. Sàng tính nhiều hàm cùng lúc¶
5.1 Dùng sàng tuyến tính¶
Với sàng tuyến tính, ta có thể tính đồng thời SPF, Euler φ, d(n), σ(n) chỉ trong \(O(N)\):
6. Ứng dụng trong thi đấu¶
6.1 Đếm số ước của N! (N giai thừa)¶
Ý tưởng: Với mỗi nguyên tố \(p \leq N\), số mũ của \(p\) trong \(N!\) là \(\sum_{k=1}^{\infty} \lfloor N/p^k \rfloor\).
(Với \(\lfloor x \rfloor\) là phần nguyên — làm tròn xuống. Công thức này hoạt động vì: mỗi bội của \(p\) đóng góp 1 nhân tử \(p\), mỗi bội của \(p^2\) đóng góp thêm 1, mỗi bội của \(p^3\) đóng góp thêm 1, ...)
6.2 Tổng ước từ 1 đến N¶
Tính \(\sum_{i=1}^{N} d(i)\) trong \(O(\sqrt{N})\) bằng Dirichlet hyperbola:
Ý tưởng Dirichlet hyperbola
Mỗi cặp \((i,j)\) với \(i \cdot j \leq N\) tương ứng với một ước. Khi \(i \leq \sqrt{N}\), ta đếm số \(j\) thỏa mãn; khi \(j \leq \sqrt{N}\), ta đếm số \(i\); rồi trừ phần đếm trùng (khi cả \(i, j \leq \sqrt{N}\)).
7. Bài tập luyện tập¶
| Mã bài | Tên bài tập | Độ khó | Kiểu bài tập (Bản chất) | Bài học lý thuyết |
|---|---|---|---|---|
snhh-spf |
SPF cơ bản | ⭐⭐ | Sàng ước nguyên tố nhỏ nhất | Sàng Nâng Cao & Hàm Ước |
snhh-divcnt |
Đếm ước nhiều truy vấn | ⭐⭐ | Đếm ước dùng SPF | Sàng Nâng Cao & Hàm Ước |
snhh-fact-multi |
Phân tích thừa số nhiều truy vấn | ⭐⭐ | Factor dùng SPF | Sàng Nâng Cao & Hàm Ước |
snhh-divsum |
Tổng ước modulo | ⭐⭐⭐ | Tổng ước dùng SPF | Sàng Nâng Cao & Hàm Ước |
snhh-sumdiv1n |
Tổng đếm ước 1..N | ⭐⭐ | Dirichlet hyperbola | Sàng Nâng Cao & Hàm Ước |
snhh-divcnt-range |
Đếm số có K ước | ⭐⭐ | Sàng số ước | Sàng Nâng Cao & Hàm Ước |
snhh-squarefree |
Đếm số square-free | ⭐⭐⭐ | Möbius lọc | Sàng Nâng Cao & Hàm Ước |
snhh-lcm-range |
LCM trên đoạn | ⭐⭐⭐⭐ | LCM \([l,r]\) | Sàng Nâng Cao & Hàm Ước |