P1099
直接把直徑揪出來從一邊到一邊掃過去就行了。
【記錄】
P5659
按照字典序貪心,對每個點維護相鄰的邊的刪除順序, 實際上細節並不多。
【記錄】
P5666
考慮計算每個點作爲重心的次數。
首先把隨便一個重心拿出來做根, 然後顯然 x 要想作爲重心就不能切 x 子樹裏的邊。(這一步真 tm 妙
)
那麼剩下的情況就是切邊後,
- x 和原來的根不在一個連通塊裏
- x 和原來的根在一個連通塊裏
如圖。
以下用 \(siz_x\) 表示以 x 爲根的子樹的節點個數。
對於切斷的邊 \(e\), 稱上面的那個點爲 \(up_e\), 下面的那個點爲 \(down_e\)。
設 \(g_x = \max\limits_{y\in son(x)}\{siz_y\}\)。
使用的重心判斷方法是去掉其後任意連通塊的大小乘 2 後都不超過整棵樹的大小。
那麼對於情況 1, 如果 x 爲重心, 那麼
- \(2\times g_x\le siz_{down_e}\)
- \(2\times (siz_{down_e}-siz_x)\le siz_{down_e}\), 即 \(2\times siz_x\ge siz_{down_e}\)
對於情況 2, 如果 x 爲重心, 那麼
- \(2\times g_x \le siz_{rt}-siz_{down_e}\)
- \(2\times(siz_{rt}-siz_{down_e}-siz_x)\le siz_{rt}-siz_{down_e}\), 即 \(2\times siz_x\ge siz_{rt}-siz_{down_e}\)
特別地, 對於根,設其最大子樹的根爲 u, 次大子樹的根爲 v, 若刪去的邊不是 u 裏面的也沒有把 u 割出去, 那麼需要滿足 \(2\times siz_u\le siz_{rt}-siz_{down_e}\); 若使 \(siz_u\) 變化了或直接沒有了, 顯然 u 這個子樹是滿足條件的, 那麼剩下的就是要判斷剩下的子樹, 即 \(2\times siz_v\le siz_{rt}-siz_{down_e}\)。
可以發現都是值域上區間查詢的形式, 不過要差分出正確的數據結構。
具體地, 對於情況 1, dfs 時維護到根的樹狀數組即可;對於情況 2, 維護全局的樹狀數組, dfs 時維護到根的樹狀數組, 利用樹上差分差分出子樹的樹狀數組。
挺簡單的, 代碼也不難寫。
【記錄】