分塊&勢能分析!!!(orz Flash!)
掛個博客表示自己還活著
之後會弄系統總結這個就當是preview好了
分塊
數列分塊入門九題(hzwer)
- 入門題1,2,3,4,5,7
問題:給一段區間打上標記後單點查詢
解法:主要是每塊維護一些標記,計算答案等,此類分塊較為簡單
註意:塊大小一般為\(\sqrt n\)
復雜度:\(O(n\sqrt n)\)
- 入門題6
問題:每次朝數列中間插入一個元素,查詢第k個元素是什麽
解法:塊大小超過一定值後暴力重構!采用鏈表實現$**
復雜度:\(O(n\sqrt n)\)
- 入門題8
問題:每次詢問一個區間內為\(c?\)的元素個數,並把整個區間改為\(c?\)
解法:維護一個區間覆蓋標記,如果塊內沒有標記就暴力修改
註意:復雜度分析要用到FlashHu的勢能分析
勢能(potential energy)是儲存於一個系統內的能量,也可以釋放或者轉化為其他形式的能量。
把一個塊攪亂,相當於給其增加\(O(\sqrt n)\)的勢能,表示其再次被打上全局tag所需要的代價
每次操作最多把兩個塊攪亂,所以每次操作最多增加\(O(2\sqrt n)\)的勢能,同時整理好一個塊需要的代價是其勢能,並能把其勢能降為\(O(1)\)
這樣子最多攪亂\(n\)個塊,增加\(O(2n\sqrt n)\)的勢能,最多把他們所有的勢能都變成\(1\),復雜度為\(O(4n\sqrt n)=O(n\sqrt n)\)
理解:增加勢能需要相應代價,減少勢能也需要相應代價,對應分析其最大勢能即可得出復雜度
拓展:分析每次可以從棧中彈出多個元素的復雜度(還是\(O(n)\),其總勢能最大為\(O(n)\))
- 入門題9
問題:在線維護區間最小眾數
解法:離線就可以用莫隊搞了
考慮分塊,分塊是一個很好的算法,維護每個數在數列中的前綴和是\(O(n^2)\)的時空復雜度,但是給分個塊就可以做到\(O(n\sqrt n)\)了
一段區間的眾數一定屬於:A.零散塊內的數 B.整塊內的眾數,一共數量不超過\(\sqrt n\)個
所以維護兩個數組:\(f[i][j]\)表示從第\(i\)塊到第\(j\)塊的眾數,這個可以\(O(\sqrt n\sqrt n\sqrt n)\)的預處理出來;\(g[i][j]\)
之後便只需要:A.統計每個數在整塊內的出現個數\(O(1×\sqrt n)\) B.統計零散塊中的數\(O(\sqrt n)\)
綜上,復雜度為\(O(n\sqrt n)\),完美通過此題/蒲公英
分塊&勢能分析!!!(orz Flash!)