2.18 ✅ Cây đoạn (Segment Tree)

- Cách hiện thực cây đoạn bằng mảng (array-based segment tree): trừu tượng hoá phần
pushUp(gộp 2 node) để có thể áp dụng cho nhiều phép toán (cộng,max,min, ...). Bài 218, 303, 307, 699. - Cách viết kinh điển của cây đoạn đếm (counting segment tree). Bài 315, 327, 493.
- Hiện thực cây đoạn dạng cây (tree-based segment tree). Bài 715, 732.
- Lazy propagation (cập nhật lười theo đoạn). Bài 218, 699.
- Rời rạc hoá (discretization). Cần chú ý trường hợp đặc biệt: giả sử có 3 đoạn , , . Nếu rời rạc hoá thành
x[1]=1,x[2]=4,x[3]=6,x[4]=10thì:- đoạn 1 thành
- đoạn 2 thành
- đoạn 3 thành
Khi đó “đoạn 1 = đoạn 2 + đoạn 3” (trong không gian rời rạc), nhưng trước khi rời rạc hoá thì rõ ràng đoạn 1 > đoạn 2 + đoạn 3. Cách đúng: chèn thêm 1 điểm khi khoảng cách > 1, ví dụ giữa
1 4 6 10chèn5→x[1]=1,x[2]=4,x[3]=5,x[4]=6,x[5]=10. Khi đó đoạn 1 là1-5, đoạn 2 là1-2, đoạn 3 là4-5.
- Xây dựng cây đoạn linh hoạt: mỗi node có thể lưu nhiều thông tin,
pushUpcũng có thể đa dạng. Bài 850, 1157.
Cây đoạn – các dạng bài từ dễ đến khó:
- Cập nhật điểm (single point update):
HDU 1166 敌兵布阵 update: tăng/giảm 1 điểm, query: tổng đoạn
HDU 1754 I Hate It update: thay thế 1 điểm, query: giá trị lớn nhất/nhỏ nhất trên đoạn
HDU 1394 Minimum Inversion Number update: tăng/giảm 1 điểm, query: tổng đoạn
HDU 2795 Billboard query: tìm vị trí có giá trị lớn nhất trong đoạn (thực hiện update ngay trong query) - Cập nhật đoạn (range update):
HDU 1698 Just a Hook update: thay thế theo đoạn (vì chỉ query 1 lần toàn đoạn nên có thể in trực tiếp thông tin node gốc)
POJ 3468 A Simple Problem with Integers update: tăng/giảm theo đoạn, query: tổng đoạn
POJ 2528 Mayor’s posters rời rạc hoá + update: thay thế theo đoạn, query: hash đơn giản
POJ 3225 Help with Intervals update: thay thế theo đoạn, XOR theo đoạn, query: hash đơn giản - Gộp đoạn (range merge) — loại bài hỏi “đoạn liên tiếp dài nhất thỏa điều kiện”, nên
pushUpphải gộp thông tin của 2 con trái/phải:
POJ 3667 Hotel update: thay thế theo đoạn, query: điểm trái nhất thỏa điều kiện - Scanline (đường quét) — cần sắp xếp các thao tác và quét từ trái sang phải; kinh điển là hợp diện tích/chu vi hình chữ nhật:
HDU 1542 Atlantis update: tăng/giảm theo đoạn, query: lấy trực tiếp giá trị ở node gốc
HDU 1828 Picture update: tăng/giảm theo đoạn, query: lấy trực tiếp giá trị ở node gốc
| STT | Tiêu đề | Lời giải | Độ khó | Độ phức tạp thời gian | Độ phức tạp bộ nhớ | Yêu thích | Tỷ lệ AC (Acceptance) |
|---|---|---|---|---|---|---|---|
| 0218 | Bài toán đường chân trời (The Skyline Problem) | Go | Hard | O(n log n) | O(n) | ❤️ | 41.9% |
| 0307 | Truy vấn tổng đoạn - có thể thay đổi (Range Sum Query - Mutable) | Go | Medium | O(1) | O(n) | 40.7% | |
| 0315 | Đếm số nhỏ hơn ở phía sau (Count of Smaller Numbers After Self) | Go | Hard | O(n log n) | O(n) | 42.6% | |
| 0327 | Đếm tổng đoạn (Count of Range Sum) | Go | Hard | O(n log n) | O(n) | ❤️ | 35.8% |
| 0493 | Cặp đảo ngược (Reverse Pairs) | Go | Hard | O(n log n) | O(n) | 30.9% | |
| 0699 | Các hình vuông rơi xuống (Falling Squares) | Go | Hard | O(n log n) | O(n) | ❤️ | 44.7% |
| 0715 | Mô-đun đoạn (Range Module) | Go | Hard | O(log n) | O(n) | ❤️ | 44.6% |
| 0729 | Lịch của tôi I (My Calendar I) | Go | Medium | 56.8% | |||
| 0732 | Lịch của tôi III (My Calendar III) | Go | Hard | O(log n) | O(n) | ❤️ | 71.5% |
| 0850 | Diện tích hình chữ nhật II (Rectangle Area II) | Go | Hard | O(n log n) | O(n) | ❤️ | 53.9% |
| 1157 | Phần tử chiếm đa số trực tuyến trong mảng con (Online Majority Element In Subarray) | Go | Hard | O(log n) | O(n) | ❤️ | 41.8% |
| 1649 | Tạo mảng đã sắp xếp qua hướng dẫn (Create Sorted Array through Instructions) | Go | Hard | 37.5% | |||
| ------------ | ------------------------------------------------------- | ------- | ---------------- | --------------- | ------------- | ------------- | ------------- |