P9999 [Ynoi2000] tmostnrq 題解

JiaY19發表於2024-06-22

巨大難寫題。

就這樣一個毒瘤的題,還有人把時空縮小成二分之一放在模擬賽,太好笑了。

思路

首先將詢問離線。

我們在 \(l_i\) 處加入這個點,在 \(r_i\) 處查詢這個點在哪裡。

那麼我們就需要有一個資料結構支援讓所有樹上的節點一起動。

考慮所有點往 \(x\) 處動。

那麼對於在 \(1\sim x\) 這條鏈上的點,需要往下走一步。

對於不在 \(1\sim x\) 這條鏈上的點,需要往上走一步。

我們可以先進行樹剖。

對每一條重鏈維護一個平衡樹。

由於我們 \(1\sim x\) 這條鏈可以拆成 \(\log\) 條重鏈。

那麼我們可以在平衡樹上暴力修改合併。

假如我們有兩個點在移動的過程中重合了,我們可以使用並查集將他們並起來。

對於不在鏈上的點,我們可以打全域性標記,找到所有需要跨鏈的點,暴力將它跨鏈。

這樣的複雜度是可以分析到 \(O(n\log^2 n)\) 的。

細節

當然,這道題最麻煩的是你如何實現。

我們可以使用 fhq-treap 來維護這個東西。

我們維護每一個點所在的鏈頭,與鏈頭的距離。

如何尋找需要跨鏈的點。

我們可以再開一顆線段樹維護。

維護每一個平衡樹上最短的與鏈頭的距離。

然後直接查詢即可。

Code

程式碼就不放了。