整體二分學習筆記
阿新 • • 發佈:2022-02-27
當對一個集合中的每個元素都要進行一樣的二分答案時,常可以對整個集合進行分治答案,將屬於答案 \([l,mid]\) 和 \([mid,r]\) 的 \(i\) 重新排列成為左右兩塊完整的,然後對左右兩塊分別遞迴處理。具體見例題。
【例】[POI2011]Meteors
對於單個元素,單調性顯然。
實現分治函式 void solve(l,r,x,y)
表示在已經預先保證下標 \([x,y]\) 的答案 \(\in [l,r]\) 的情況下,將下標區間 \([x,y]\) 按答案 \(\in [l,mid]\) 和 \(\in [mid+1,r]\) 分成兩類。主函式中只用呼叫 solve(1,q+1,1,n)
我們可以讓 \([l,mid]\) 的流星雨都下下來,來看一下現在有哪些是已經滿足了的,把這些放在左邊,就是說答案應該在 \([l,mid]\) 中的(\(<mid\)),而反之放到右邊,因為答案 \(>mid\)。假如分界點是 \(w\),那麼接著遞迴
solve(l,mid,x,w)
和 solve(mid+1,r,w+1,y)
;執行此操作前將 \([w+1,y]\) 的 \(p\) 減去這次已經統計到的(因為每次加的 \([l,mid]\) 而不是 \([1,mid]\))。直到 l==r
時,將 ans[x]...ans[y]
都設為 l
注:本題需要一些卡常,比較有效的是
- 在
get()
中if(s>p[x])
可以直接返回s
了,因為繼續加下去沒任何意義 - 不要
memset
樹狀陣列,而是“還原現場”,實測 85pts->100pts