1. 程式人生 > 其它 >整體二分學習筆記

整體二分學習筆記

當對一個集合中的每個元素都要進行一樣的二分答案時,常可以對整個集合進行分治答案,將屬於答案 \([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)

。(q+1是用來判無解的,不必在意)
我們可以讓 \([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
回溯。

https://loj.ac/s/1391125

注:本題需要一些卡常,比較有效的是

  1. get()if(s>p[x]) 可以直接返回 s 了,因為繼續加下去沒任何意義
  2. 不要 memset 樹狀陣列,而是“還原現場”,實測 85pts->100pts

https://loj.ac/s/1391148