Professional Documents
Culture Documents
Solution XORPATH
Solution XORPATH
Solution XORPATH
Cho 𝑞 (𝑞 ≤ 105 ) truy vấn, mỗi truy vấn thuộc một trong hai loại:
Đặt đỉnh 1 là gốc của cây. Tính 𝑝𝑟𝑒𝑓𝑖𝑥𝑋𝑜𝑟[𝑢] là tổng 𝑥𝑜𝑟 trên đường
đi từ đỉnh 1 đến đỉnh 𝑢. Việc tính 𝑝𝑟𝑒𝑓𝑖𝑥𝑋𝑜𝑟 có thể thực hiện bằng
DFS/BFS trong 𝑂(𝑛) như sau:
0 𝑛ế𝑢 𝑢 = 1
𝑝𝑟𝑒𝑓𝑖𝑥𝑋𝑜𝑟 𝑢 = 𝑝𝑟𝑒𝑓𝑖𝑥𝑋𝑜𝑟 𝑣 𝑥𝑜𝑟 𝑤 (𝑣 𝑙à 𝑐𝑎 𝑢 𝑣à
𝑤 𝑙à 𝑡𝑟ọ𝑛𝑔 𝑠ố 𝑐ạ𝑛 𝑛ố𝑖 𝑣 − 𝑢)
Lúc này kết quả của truy vấn 2 sẽ là 𝑝𝑟𝑒𝑓𝑖𝑥𝑋𝑜𝑟 𝑢 𝑥𝑜𝑟 𝑝𝑟𝑒𝑓𝑖𝑥𝑋𝑜𝑟[𝑣].
Vậy xử lý truy vấn 2 mất 𝑂(1). Tuy nhiên với truy vấn 1, nếu gán trọng
số mới rồi DFS/BFS để tính lại 𝑝𝑟𝑒𝑓𝑖𝑥𝑋𝑜𝑟 sẽ vẫn mất 𝑂(𝑛) cho mỗi
truy vấn !!!
Để ý một chút, khi cập nhật lại trọng số cạnh 𝑢 − 𝑣 (giả sử 𝑣 là con 𝑢)
thì không phải tất cả các giá trị của 𝑝𝑟𝑒𝑓𝑖𝑥𝑋𝑜𝑟 đều thay đổi mà chỉ có
những giá trị 𝑝𝑟𝑒𝑓𝑖𝑥𝑋𝑜𝑟[𝑥] bị thay đổi, trong đó 𝑥 là những nút trong
cây con gốc 𝑣. Nếu trọng số cũ là 𝑜𝑙𝑑𝑊 và trọng số mới là 𝑤 thì
Nếu sắp xếp các đỉnh theo thứ tự duyệt DFS (đỉnh nào duyệt trước thì
đứng trước) thì chắc chắn các nút trong cây con gốc 𝑢 sẽ là các phân
tử liên tục trong dãy này.
Quan sát sẽ thấy các nút trong 1 cây con sẽ là 1 dãy liên tục, ví dụ các
nút trong cây con gốc 5 là 5, 8, 7 hay các nút trong cây con gốc 3 là 3,
6.
Quên cây đi ! Bài toán đã trở thành bài toán truy vấn trên dãy
Cho một dãy A gồm 𝑛 phần tử và 𝑞 truy vấn. Có 2 loại truy vấn:
Đây là 1 bài toán quen thuộc trên cây IT. Dựng 1 cây IT lưu
tổng/min/max. Với truy vấn 1 bạn cập nhật đoạn trên IT trong
𝑂(𝑙𝑜𝑔𝑛) và truy vấn 2 là lấy giá trị 1 phần tử trong 𝑂(𝑙𝑜𝑔𝑛). Như vậy
độ phức tạp toàn bài là 𝑂(𝑛 + 𝑞 ∗ 𝑙𝑜𝑔𝑛).
Chưa học đến cây IT hay chưa biết cách cập nhật đoạn trên cây IT thì
làm sao?
Nếu bạn đã học cây BIT rồi thì vẫn có thể giải quyết được bài toán mà
không cần sử dụng cây IT với cập nhật đoạn, thậm chí code ngắn hơn.
Khi muốn thực hiện truy vấn loại 1 ở bài toán mới, ta chỉ cần gán
𝐴 𝑙 = 𝐴 𝑙 𝑥𝑜𝑟 𝑤, 𝐴 𝑟 + 1 = 𝐴 𝑟 + 1 𝑥𝑜𝑟 𝑤. (cập nhật 2 phần tử
trong 𝑂(𝑙𝑜𝑔𝑛)).
Khi muốn thực hiện truy vấn loại 2 ở bài toán mới, kết quả là
𝐴 1 𝑥𝑜𝑟 𝐴 2 𝑥𝑜𝑟 … 𝑥𝑜𝑟 𝐴 𝑢 𝑥𝑜𝑟 (𝐴 1 𝑥𝑜𝑟 𝐴 2 𝑥𝑜𝑟 … 𝑥𝑜𝑟 𝐴 𝑣 )
(Truy vấn trong 𝑂(𝑙𝑜𝑔𝑛)).
Việc chứng minh thủ thuật trên là đúng xin nhường lại cho bạn đọc.
Như vậy vẫn cùng độ phức tạp nhưng lại có thể code ngắn hơn và
không cần quá nhiều kiến thức, bạn vẫn có thể giải quyết bài toán dễ
dàng.