動態dp學習筆記
阿新 • • 發佈:2018-11-27
\(noip\)考了,趕緊補一發。
不得不說網上的題解還是不錯的ljq的程式碼吼啊
- 一開始看的部落格
- 模板
其實我感覺看部落格不如看別人優秀的程式碼來的快首先是樹鏈剖分的思想
- 講一講自己的感想
- 首先我們為了使得\(f\)帶修改,引入了樹鏈剖分套線段樹維護矩陣進行\(dp\)。
- 但是這樣我們是無法直接維護\(f\)的,因為剖分的思想是重鏈不會超過\(log\)次劃分。
- 假設我們現在可以一次性跳完整個重鏈,那麼問題就變成了是否可以從重鏈頂跳到上一個重鏈
- 於是我們引入新陣列\(g\),表示不算當前重鏈的所有貢獻。
- 那麼我們只需要維護\(g\),每次修改就直接把整個重鏈的\(g\)
- 此時我們發現,不是每個地方的\(f\)都是有意義的。
- 首先我們知道每個位置的\(g\),然後用線段樹維護他。
- 維護\(g\)的原因是我們可以通過線段樹優化\(dp\)轉移使得在\(log\)的時間內得到一段的\(g\)卷積。
- 所以我們只知道每個鏈頂的\(f\)值,而並不關心每個點的\(f\)。
- 那麼問題就簡單多了,對於每次修改,我們只需要修改當前點的\(g\),然後\(\prod\)到鏈頂的\(f\),再用當前的\(f\)更新父親的\(g\),重複這個操作。
- 實際上我們又給出了\(f\)的新定義,即\(f=\prod g\)
- 總結一下就是:
- 個人認為動態\(dp\)的思想在於整體考慮一整個重鏈的\(dp\)轉移。
- 然後再把這個重鏈的\(dp\)轉移貢獻給鏈頂父親
- 那麼在實際設計狀態的時候,形如\(g_{i,j}\)表示\(i\)點不考慮重兒子的\(dp\)值。
- 然後根據狀態轉移方程一次性考慮一整個重鏈
- 這樣的話,我們在修改操作的時候,就只需要考慮鏈與鏈之間的關係了。
至此,我們得到了一個\(O(4*q*log^2n)\)的做法。
但是這樣還是不夠優秀
晚上更。