Giải thích: Phiên bản 1 chứa các cạnh nối 0−1−2, còn phiên bản 0 chỉ có cạnh 0−1. Phiên bản 4 được tách từ gốc và chỉ nối 2−3, nên bốn truy vấn lần lượt nhận 1,0,1,0.
Lời giải tóm tắt
Phân tích: Không cần sao chép DSU cho từng phiên bản. Ta dựng cây cha phiên bản, duyệt DFS và dùng một DSU rollback: state trên đường từ gốc đến nút hiện tại chính là state của phiên bản đó.
Thuật toán: Đổi phiên bản -1 thành nút gốc 0, còn thao tác i thành nút i+1. Thêm cạnh cây từ k+1 tới i+1. Khi vào một nút union, chụp snapshot rồi hợp hai đỉnh; khi vào nút query, đọc hai gốc và lưu đáp án. Sau khi duyệt xong toàn bộ con, rollback về snapshot trước nút. DSU dùng union-by-size, không path compression và lưu sentinel cho union dư thừa.
Chứng minh: Quy nạp theo DFS. Trước khi xử lý một nút, DSU chứa đúng các phép union trên đường từ gốc tới cha nó. Áp thao tác union của nút (hoặc không đổi state với query) tạo chính xác phiên bản của nút. Vì vậy query được trả lời đúng. Sau khi xử lý mọi con, rollback xóa đúng thay đổi của nút, trả DSU về state của cha trước khi sang nhánh anh em. Do đó mọi phiên bản đều được xử lý đúng và độc lập.
Độ phức tạp: Mỗi thao tác được áp và rollback một lần; thời gian O(q log n), bộ nhớ O(n+q).