Bài 58: Nguyên Lý Bao Hàm - Loại Trừ¶
Tác giả: FPTOJ Team
Nội dung tham khảo từ: CP-Algorithms, VNOI Wiki
1. Nguyên Lý Cơ Bản¶
1.1 Công thức 2 tập¶
Cho hai tập \(A\) và \(B\), số phần tử trong hợp:
Trừ đi phần giao vì đã đếm hai lần.
1.2 Công thức 3 tập¶
1.3 Công thức tổng quát (n tập)¶
Hoặc viết gọn:
Tương tự, đếm phần bù (những phần tử KHÔNG thuộc tập nào):
2. Ví dụ trực quan¶
2.1 Đếm số không chia hết cho 2, 3, hoặc 5 trong [1, 100]¶
Gọi: - \(A\): số chia hết cho 2 → \(|A| = \lfloor 100/2 \rfloor = 50\) - \(B\): số chia hết cho 3 → \(|B| = \lfloor 100/3 \rfloor = 33\) - \(C\): số chia hết cho 5 → \(|C| = \lfloor 100/5 \rfloor = 20\)
Giao: - \(|A \cap B| = \lfloor 100/6 \rfloor = 16\) - \(|A \cap C| = \lfloor 100/10 \rfloor = 10\) - \(|B \cap C| = \lfloor 100/15 \rfloor = 6\) - \(|A \cap B \cap C| = \lfloor 100/30 \rfloor = 3\)
Áp dụng:
Số không chia hết cho 2, 3, 5: \(100 - 74 = 26\).
3. Cài Đặt Tổng Quát¶
3.1 Duyệt tất cả tập con bằng bitmask¶
Khi số điều kiện \(n\) nhỏ (≤ 20), duyệt tất cả \(2^n\) tập con:
Độ phức tạp: \(O(2^n \cdot n)\) cho mỗi truy vấn.
4. Derangements (Hoán vị không có phần tử cố định)¶
4.1 Bài toán¶
Đếm số hoán vị của \(\{1, 2, \ldots, n\}\) sao cho không phần tử nào đứng nguyên vị trí.
4.2 Công thức¶
Gọi \(A_i\) là tập hoán vị mà phần tử \(i\) đứng nguyên vị trí. Cần đếm phần bù.
Tại sao công thức này đúng?
Áp dụng inclusion-exclusion: bắt đầu từ \(n!\) (tổng hoán vị), trừ đi các hoán vị có ít nhất 1 phần tử đứng đúng (\(\binom{n}{1}(n-1)!\)), cộng lại các hoán vị có ít nhất 2 phần tử đứng đúng (\(\binom{n}{2}(n-2)!\)), ... Sau khi rút gọn ta được công thức trên. Mỗi hệ số \(\frac{(-1)^k}{k!}\) tương ứng với việc chọn \(k\) phần tử cố định tại chỗ.
Hoặc truy hồi: \(D(n) = (n-1)(D(n-1) + D(n-2))\), \(D(1) = 0, D(2) = 1\).
5. Đếm hoán vị có phần tử bị cấm¶
5.1 Bài toán¶
Cho \(n\) phần tử, mỗi phần tử \(i\) có một tập \(B_i\) các vị trí bị cấm. Đếm số hoán vị mà phần tử \(i\) không đứng ở vị trí nào trong \(B_i\).
5.2 Giải bằng Inclusion-Exclusion¶
Với mỗi tập con \(S\) của các điều kiện "vi phạm", tính số hoán vị thỏa mãn tất cả vi phạm trong \(S\), rồi cộng/trừ theo công thức.
6. Surjection (Ánh onto)¶
6.1 Bài toán¶
Đếm số ánh xạ từ tập \(n\) phần tử onto tập \(k\) phần tử (mỗi phần tử trong tập đích phải được ánh tới ít nhất một lần).
6.2 Công thức¶
Tại sao công thức này đúng?
Áp dụng inclusion-exclusion: \((k-i)^n\) là số ánh xạ mà ít nhất \(i\) phần tử trong tập đích không được ánh tới (chỉ ánh vào \(k-i\) phần tử còn lại). \(\binom{k}{i}\) là cách chọn \(i\) phần tử bị bỏ qua. Dấu \((-1)^i\) là hệ số inclusion-exclusion.
7. Grid Paths với vật cản¶
7.1 Bài toán¶
Đếm số đường đi từ \((0,0)\) đến \((n,m)\) trên lưới, không đi qua các ô bị cấm.
7.2 Sắp xếp và Inclusion-Exclusion¶
Sắp xếp các ô cấm theo thứ tự. Với mỗi ô cấm \(i\), đếm số đường đi từ gốc đến \(i\) mà không qua ô cấm nào khác, rồi trừ đi phần đóng góp vào đích.