Kruskal重構樹
不支持時間旅行的可持久化並查集
給定 n 個點, 以及 m 次操作, 操作有兩種:
① 將點 x 與點 y 進行連邊;
② 詢問在前 t 次操作操作中, x 與 y 是否連通.
n <= 100000, 強制在線.
核心模型
n 個點, m 條帶權邊的無向圖.
多次詢問點 x 和點 y 在邊權不超過 w 的邊的作用下的連通性信息(例如, 是否連通).
強制在線.
對於不支持時間旅行的並查集問題, 將時間這一維給量化之後, 可以等價地看成這個核心模型.
對於操作①, 我們相當於連邊 (x, y) , 邊權為 t .
對於操作②, 相當於查詢邊權不超過 t 的邊的作用下, x 和 y 是否連通.
問題解決
假如可以離線, 那麽我們就有 Kruskal + 並查集 的做法.
從小到大, 每連接一條邊, 就將連接下一條邊前的詢問進行回答.
現在要求在線, 我們嘗試維護歷史版本的並查集.
我們考慮在並查集存儲更多的信息, 從而也使用更適合的按秩合並的方法, 而不使用更快的路徑壓縮的方法.
將點 x 的父親設為 y 的時候, 我們考慮多記錄 w 數組, w[x] = 當前連邊的邊權.
我們當前要查找在不超過 d 的邊權的作用下, x 在並查集的代表元素.
我們從查詢的點開始跳, 當且僅當 d >= w[x] , 那麽代表元素是 x 的祖先.
如此下來, 我們能找到並查集的代表元素, 且復雜度為 O(n log n) .
Kruskal重構樹
我們把利用 f[], w[] 兩個數組構建出來的樹叫做 Kruskal重構樹 .
我們可以輕易地查詢在邊權不超過 d 的邊的作用下, x 對應的並查集的代表元素 a . 我們還可以知道更多的信息, 因為與 x 連通的元素的集合就是 a 的子樹對應的集合.
所以, 這棵樹的作用可以概括為: 詢問 x 在邊權不超過 d 的邊的作用下的連通性信息.
以強制在線 Peaks 一題為例.
給定一張圖, m 次詢問 (x, k): 在邊權不超過 d 的邊的作用下, 與 x 連通的所有點中點權第 k 小是多少?
我們考慮利用並查集構建出 Kruskal 重構樹, 我們找邊權不超過 d 的邊的作用下, x 的代表元素 a , 那麽相當於查詢子樹 a 的所有點的點權第 k 小.
Kruskal重構樹