整体二分学习笔记

当对一个集合中的每个元素都要进行一样的二分答案时,常可以对整个集合进行分治答案,将属于答案 \([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

posted @ 2022-02-25 22:02  pengyule  阅读(24)  评论(0)    收藏  举报