動態點分治入門隨講

扯兩句淡

爲何叫入門隨講呢……由於我也剛學完啊html

 

前置技能

點分治(這不是要學動態點分治嗎)算法

線段樹(會點分治不會線段樹?)數據結構

其實線段樹是來幫助理解的。spa

 

爲好友打廣告(利用好友優秀博文提高×格)

句句經典……在點分上沒有必定造詣還真寫不出來。htm

牆裂推薦一觀,文筆和思想都比某hr好多了。blog

淺談對點分治的一些理解——qt666排序

 

正文

引入

點分治是一種人人喜歡的算法。它含鈣高,吸取好思想比較簡單,代碼實現也不難,複雜度瓶頸在統計跨重心root的鏈對答案的影響/貢獻。get

可是點分治的缺點是很明顯的:它只能作離線問題!換句話說,它不支持修改操做。qt

這個時候就須要動態點分治來幫幫忙了。  io

 

算法原理

這個時候咱們已經對點分治的理解很深了。它經過巧妙地在k級重心處劃分,把樹上的路徑劃分紅了兩類:通過重心的和不通過重心的。

之因此複雜度有保證,是由於每一個點做爲鏈端點只會被統計log次。

帶修改的話,暴力確定是詢問一次作一次點分。

注意到修改的基本是點權之類的而不是樹的形態。換言之,每次的點分過程是同樣的!

而後又想到每一個點只會被統計log次——胡不重構此樹乎?

講清楚點:既然每次修改只會改一個點,只會把它做爲端點的鏈的信息改掉。

(要是你改一個點會引發多個點改動也不像是樹分治題而更像傳統數據結構題)

其餘的點的信息該是多少仍是多少,是不變的過往,是永恆的黑暗與孤獨——打住。

屢次處理重複相同信息,是必不可能被咱們所稱讚的。而這些信息總的數量級又只有O(nlogn)級別。

爲何不把它事先保存,而後對於每次修改,O(logn)級別地暴力一一修改呢?

每次查詢,要麼直接取,要麼暴力跳一個點的重心祖先鏈,複雜度也很優秀。

即:預處理點分治一遍,把分級重心樹搞出來,把信息存進去。

每次操做,修改即想辦法修改本身到祖先重心鏈上的信息便可。

詢問呢,你都維護了這麼多東西了,也是想辦法快速求就能夠了。

好比說取最大值,那就開堆嘛(ZJOI捉迷藏)。

再好比說HNOI開店,用vector動態申請空間,排序一下,每次詢問暴跳祖先。

提及來好像很簡單,實現起來倒是如人飲水冷暖自知。

 

剩下的我一時也不知道還能講什麼了?……

送一句話:樹上的動態點分治就至關於序列上的線段樹。

忘記是從哪一個神犇那蒯的了……

 

最後也送一點套路

兩點lca什麼的別用倍增了,用歐拉序列+ST表預處理O(1)搞定。

還有記得把log也預處理出來,系統超慢。

開堆開桶之類的,vector或new

相關文章
相關標籤/搜索