複習 動態點分治

2021-08-21 11:02:39 字數 1310 閱讀 1594

點分治,動態點分治,等等等各種分治。

因為我的智商經常欠費,導致我對於分治這個方面一竅不通。

但是動態點分治這個東西我又不是沒有學過,只是過了這麼久我什麼都不會了。

所以還是重新理解一下吧。。。

首先,動態點分治需要構建出點分樹,這個很好處理。

找重心是o(

n)o (n

),每次重心分出來的每一棵子樹的大小都不超過o(

n/2)

o (n

/2

)所以總的複雜度是o(

nlog

n)o (n

logn

)的。

點分樹中的父子關係和原樹中差距較大,但是並不影響我們對於資訊的維護。

點分樹的樹高是lo

g log

級別的,因此在點分樹上暴力向上維護的複雜度是正確的。

因為點分樹上的父子關係和原樹的父子關係差距較大,

我們來考慮如何維護點分樹上的資訊。

按照題目來舉例子,比如【bzoj3730】震波

我們需要維護的東西是對於當前點距離不超過

x x

的點。

我們看看在原樹中這個東西怎麼找:

我們確定乙個根,轉化為有根樹。

對於每個點維護距離它不超過

x' role="presentation">x

x的所有子樹中的點,統計一下。

然後跳到父親,統計一下距離父親距離不超過x−

1 x−1

的所有子樹中的點,

但是發現當前點中有一部分被重複算了,所以再減去距離當前點子樹中距離不超過x−

1 x−1

的點。

然後繼續跳到父親的父親……

因為點分樹上的所有點的,都是原樹中一棵子樹的重心,

我們可以認為點分樹上所有點的子樹就是這個點在原樹上的子樹,只不過我們看的根不太一樣而已。

既然這樣,我們就可以向上面那樣求解:

維護距離當前點不超過

x x

的所有子樹中的點。

跳到父親,假設父親和當前點的距離為

d' role="presentation">d

d,找一下距離父親不超過

d d

的點。

然後減去距離當前點距離不超過

d' role="presentation">d

d的所有點。

然後跳到父親的父親……

這樣是對的原因也很簡單:當前點一定是點分樹上父親的子樹中的乙個點。

那麼我們在維護這個點的同時,只需要像上面所寫的那樣,再維護一下當前點對於父親的貢獻就好了。

點分治 動態點分治

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

點分治與動態點分治

點分治一般是用於解決樹上路徑問題。樹的重心 把重心這個點割掉後,使所形成的最大的聯通塊大小最小的點。可以證明重心子樹的大小最大不會超過 n over 2 重心可以通過 dfs 一遍求出。maxsiz x 表示割掉點x後所形成的的最大的聯通塊的大小 void dfs int x,int fa max ...

點分治 複習筆記

之前diaoye的一道題是要用點分治寫.但是我省選前臨時學的點分治,當時又只打了幾個板子,中間又沒有寫過有關的題,於是現在就似乎不太會了,剛好昨天又講了,今天就複習一下 引用講課pp t ppt 裡的一段話 點分治,是處理樹上路徑 連通塊的一種常見演算法。這一類問題有時可以通過lca來處理,但是有的...