水平不高, 內容比較簡單.
內容難度不隨章節單增.
0. 雜七雜八
做題做到什麼東西都會扔到這裏. 想到啥寫啥.
-
如果要求統計樹上所有點對之間的貢獻, 可以考慮枚舉 lca. (CF1856E1)
-
如果有類似於樹上經過的邊的權值 \(\leq k\) 這樣的限制, 可以把邊按照邊權排序再往裏面加. 要求是能快速算出把兩個連通塊連起來的貢獻. (CF1857G)
-
如果所有詢問都是從根到一個結點這樣的, 可以直接在 dfs 時維護加入/撤銷. (AT_abc302_h)
-
把一些點連起來的最小連通塊: 利用虛樹結論, 維護 dfs 序相鄰的點, 但是寫起來簡單地多. (CF176E)
-
中途換根對子樹和 lca 的影響: 分類討論即可. (CF916E)
1. 重鏈剖分
用於路徑/子樹的修改詢問.
大致思路是, 嘗試用線段樹來維護 dfs 序. 子樹是容易的.
對於鏈, 如果能夠讓 dfs 序連續, 那也是容易的. 爲了儘可能做到 dfs 序的連續, 我們每次先 dfs 重兒子, 這樣形成若干條重鏈. 因爲到根的路徑可以拆成 \(O(\log n)\) 條重鏈, 該算法時間複雜度正確.
(過於簡單, 不給例題了)
2. 樹上線段樹合併
直接上題目.
例 1: P4556 [Vani有約會] 雨天的尾巴 /【模板】線段樹合併
例 2: P6773 [NOI2020] 命運
3. dsu on tree / 樹上啓發式合併
不帶修子樹詢問.
4. 長鏈剖分
這個東西可以 \(O(n\log n)-O(1)\) 求樹上 k 級祖先, 不過用處不大.
比較重要的是, 長鏈剖分可以用來優化只與深度有關的 dp.
例 1: CF1009F Dominant Indices
例 2: P5904 [POI2014] HOT-Hotels 加強版
例 3: P4292 [WC2010] 重建計劃
5. 點分治
一般用來統計路徑.
具體操作是, 選定一個點 (樹的重心), 一次做完所有經過這個點的路徑, 然後只需到各個子樹繼續統計.
例 1: P4178 Tree
簡單題. 使用點分治, 直接考慮怎麼統計經過一個點的路徑.
爲了避免統計到兩個點在一個子樹裏的情況, 我們可以對每棵子樹, 先查它的貢獻, 再加進去.
於是直接 dfs 求深度, 用個樹狀數組統計一下就完事了.
時間複雜度 \(O(n\log n\log k)\).
例 2: CF293E Close Vertices
實際上還有邊分治這樣的東西, 原理差不多, 並且只會出兩個子樹, 比較好討論. 但是邊分需要三度化, 很難寫.
6. 單側點分治
名字是隨便起的. 直接看題.
例 1: P4886 快遞員
例 2: CF566C Logistical Questions
7. 點分樹
8. 虛樹
用於每次詢問和點集有關的問題, 這時需要一個只與點集大小相關的算法而不需要原來的樹.
方法是一開始求出來每個點的 dfs 序, 然後詢問的時候, 把相鄰兩個點的 lca 拉出來建樹 (結論). 然後對着建出來的虛樹進行操作即可.