Ba nhóm phủ đủ mọi cặp
```python
def getInvCount(A, left, right, temp):
if left >= right:
return 0
mid = (left + right) // 2
countL = getInvCount(A, left, mid, temp)
countR = getInvCount(A, mid + 1, right, temp)
countM = merge_count(A, left, mid, right, temp)
return countL + countR + countM
```
Với mỗi cặp chỉ số ban đầu i<j, hoặc cả hai ở trái, hoặc cả hai ở phải, hoặc i ở trái và j ở phải. Ba nhóm không chồng nhau nên cộng countL,countR,countM. Cơ sở miền rỗng hoặc một phần tử trả 0.
Hai lời gọi nhỏ sắp xếp từng nửa trong A; bước merge_count vừa trộn chúng vừa đếm cặp chéo. Dãy A ở đây bị sửa thành thứ tự không giảm, nên cần giữ bản gốc nếu còn dùng để đối chiếu.
Tạo bản sao và dãy tạm một lần
```python
def count_fast(A):
B = A.copy()
temp = [0] * len(B)
return getInvCount(B, 0, len(B) - 1, temp)
```
Chạy tại thư mục chứa mã:
```text
python3 g11-cs-thuc-hanh-chia-de-tri.py dem "6 2 6 1"
```
Hai dòng đếm cần cùng cho 4. count_fast giữ A gốc bằng bản sao B; temp tạo một lần rồi truyền tới các lời gọi. Không đếm lại trên B đã được sắp để kiểm số nghịch đảo của dữ liệu ban đầu.
Bước trộn tốn O(n), hai nửa tạo công thức T(n)=2T(n/2)+O(n), nên bản chỉ đếm có O(n log n). Dãy rỗng/một phần tử/toàn bằng nhau đều cho 0; thử thêm dãy giảm và đối chiếu với count_simple.
Bài luyện
Vì sao có thể cộng countL+countR+countM?
Cặp nằm trong nửa phải vẫn thuộc bài toán.
Ba nhóm tách biệt và phủ đủ các khả năng của cặp chỉ số.
Nếu cùng đếm thì phép cộng sẽ lặp.
countM chỉ tính cặp chéo của mức đang xét.
Lời giải
Hai chỉ số hoặc cùng ở trái, cùng ở phải, hoặc nằm hai phía theo thứ tự. Không có nhóm thứ tư và không cặp nào thuộc hai nhóm, nên cộng ba số đếm là đúng.
Bài luyện
Vì sao count_fast tạo B=A.copy()?
Bản sao vẫn có thứ tự gốc lúc bắt đầu.
Hàm vẫn trả số lượng.
Bản đếm nhanh có bước ghi thứ tự đã trộn.
copy giữ đủ phần tử.
Lời giải
getInvCount sửa dãy làm việc qua các bước trộn. Tạo B giữ A gốc để bản đếm đơn giản hoặc phép liệt kê còn đối chiếu đúng dữ liệu ban đầu.
Bài luyện
Bản chỉ đếm dùng trộn có bậc thời gian nào theo mô hình thao tác cơ bản?
Cần cộng công việc của mọi nhánh và bước trộn.
Số lượng đầu ra không quyết định toàn bộ công việc.
Cách này cộng nhiều cặp cùng lúc bằng mid−i+1.
Hai nhánh và trộn tuyến tính tạo cùng dạng truy hồi với sắp xếp trộn.
Lời giải
Hai nửa đều được giải; bước trộn cộng số cặp chéo theo nhóm trong thời gian tuyến tính. Có khoảng log n mức với O(n) công việc mỗi mức, nên O(n log n).
Đang học