點分治小結

2021-09-25 21:54:14 字數 564 閱讀 6787

最近學了學點分治,畢竟oj上都搞了個專題了。

以乙個點為界限,將一棵樹分成若干個子樹,當劃分到一定規模,就對每個子樹分別進行求解

我們為了保證時間,所以要使子樹大小盡量小。

如何找到最優的點呢?就是重心!

重心是什麼?

1.求當前樹重心。

2.計算答案。

3.走到相鄰未操作的節點進行第1步。

暴力\(o(n)\),找到乙個點,使得所連子樹的大小的最大值最小。

\(bz\)陣列表示其有沒有走過(走過就不是當前樹了)

void getrt(int x, int fa)

if (son[x] < tot - siz[x]) son[x] = tot - siz[x];

if (son[x] < son[rt]) rt = x;

}

可證明為\(o(log^n_2)\)。

由於重心有乙個性質:

樹的重心的每棵子樹大小一定小於等於\(n/2\)。

所以就可以證明啦。

詳見oj

點分治小結

終於理解了點分治。不過感覺這東西的拓展一定很高深。bzoj3697 套路 乙個個子樹列舉,單獨考慮根出發的貢獻。點分治的本質就是合併相同的資訊來優化複雜度。xjoi 第k大 給定一棵帶權值的樹,求每個點出發的第k小距離。可以在dfs序上分塊,維護全域性第k大然後一遍dfs。點分 常見的在點分樹上統計...

P3806 模板 點分治1 (點分治小結 )

分治點既然是分治,我們肯定每一次都要選擇乙個點,從他開始分治下去。那麼考慮我們如何選擇這個點呢?我們發現,每一次處理完乙個點之後,我們都要遞迴進它的子樹,那麼時間複雜度受到它最大的子樹的大小的影響。比如,如果原樹是一條鏈,我們選擇鏈首,一路遞迴下去,時間複雜度毫無疑問是o 實際上,一棵樹的最大子樹最...

點分治 動態點分治

實在拖得太久了。先扔掉資料 分治的核心是盡量把乙個整體分成接近的兩個部分,這樣遞迴處理可以讓複雜度從n 變成nlogn。兩個問題,如何區分和如何算答案。對於第乙個問題,重心,然後就是找重心的方法,兩個dfs,對於第二個問題,對於每個重心算當前塊中每個點到重心的答案,然後由重心分開的塊要把多餘的資訊去...