UOJ794. 【UR #24】位元之地

zzzYheng發表於2024-09-21

題意:

https://uoj.ac/problem/794

思路:

可以發現這是一個類網格圖最短路的問題,因此可以考慮 旅行者 中的技巧:每次找到一個點集 \(s\),計算過點集 \(s\) 的所有路徑貢獻,然後刪除點集 \(s\),對剩餘的每個連通塊遞迴執行這個過程。

顯然比較好的點集 \(s\) 需要滿足以下性質:

  • 點集 \(s\) 要比較小,這是為了保證計算過 \(s\) 路徑的貢獻的複雜度。
  • 刪去點集 \(s\) 後圖要裂成至少兩個連通塊,且每個連通塊的大小較為均勻。

那麼現在的目標就是每次在圖中尋找一個比較優的 \(s\)

首先這個圖是不可能比網格圖更優的,所以我們考慮尋找 \(\Theta(\sqrt{n})\) 大小的 \(s\)

還是考慮類似的根號分治,我們先考慮樹高不超過 \(\sqrt{n}\) 的情況,此時可以考慮豎向劃分。

此時我們可以直接找到 \(dfn\) 序最中間的點 \(p\),選擇其到跟鏈,這樣劃分非常均勻,但是左右兩個部分並沒有完全斷開,它們還可以從下方繞過去。

因此如果 \(p\) 不是葉子,我們可以將其 \(dfn\) 序最小的兒子加入;如果 \(p\) 是葉子,注意此時如果 \(p\) 不在最後一層,那麼左右兩邊還是可以透過下面的點連通,不過我們選擇 \(s\) 並沒有一定要選鏈的要求,所以可以選擇下一層中 \(dfn\)\(p\) 大的第一個點加入 \(s\),重複這個過程。

可以發現這樣就得到了一個符合要求的 \(s\) 了,可以發現左右兩邊是不可能繞過 \(s\) 連通的。

對於樹高超過 \(\sqrt{n}\) 的情況可以考慮橫向劃分,因為一定存在一行大小不超過 \(\sqrt{n}\)

可以找到最中間的一行 \(l_1\),滿足上面和下面的大小都不超過 \(\frac{n}{2}\)

但是這一行的大小可能超過 \(\sqrt{n}\),不能直接劃開這一行。

但是在 \(l_1\)\(\sqrt{n}\) 行內一定會存在一行 \(l_0\) 大小不超過 \(\sqrt{n}\)(可能為 \(0\),即連通塊在這裡結束了),同理 \(l_1\) 下方 \(\sqrt{n}\) 行內一定會存在一行 \(l_2\) 大小不超過 \(\sqrt{n}\)

我們可以把 \(l_0\)\(l_2\) 割開,這樣 \(l_0\) 上方和 \(l_2\) 下方兩個連通塊大小就都不超過 \(\frac{n}{2}\),滿足條件。不過 \(l_0\)\(l_2\) 中間的部分仍可以很大,不過這個部分的樹高一定不超過 \(\sqrt{n}\),我們再使用豎向劃分的方法即可。

這樣複雜度是 \(T(n)=2T(\frac{n}{2})+n^{1.5}=n^{1.5}\)

相關文章