整体二分
整体二分
济南qbxt的意外收获
什么是整体二分:
一般情况下,我们用的二分是对答案进行,但总会有这么一种情况要进行多次二分操作。所以,就有人发明了整体二分这种骚操作。
整体二分主要是把所有询问放在一起二分答案,然后把操作也一起分治。
什么时候用呢?
- 当你发现多组询问可以离线的时候。
- 当你发现询问可以二分答案而且check复杂度对于单组询问可以接受的时候。
- 当你发现询问的操作都是一样的的时候。
其实就是题目允许离线,并且询问可以通过二分回答时,可以使用整体二分。
现在我们想想:二分答案的时候,对于一个答案,是不是有无用操作,或有些操作贡献是不变的?
比如二分一个时间,那么时间后面发生的操作就是没有用的,时间前面的贡献是不变的。
二分一个最大值,比mid大的都是没用的,比mid小的个数是一定的。
整体二分就是利用了这么一个性质。
做法与时间复杂度分析:
假设所有的询问按时间顺序构成序列 $ Q = (q_1,q_2\cdots q_p) $ ,所有询问,的答案都落在区间 $ [L_0, R_0]$ 当中。
首先得到区间 $ [L_0, R_0] $ 的中点 $ mid $,将序列分成两个不相交的部分 $ Q_1,Q_2 $,满足 $Q_1 \cup Q_2 = Q $ ,
序列 $ Q_1 $ 中所有询问的答案不超过 $ mid $ , $ Q_2 $ 中所有询问的答案全部大于 $ mid $ 。
对 $ Q_1, Q_2 $ 递归执行以上步骤, 要求对于任意一个子序列 $ Q′ $ 和对应的区间 $ [l, r] $,将 Q′ 分成两部分的时间不超过 $ O(jQ′j) $,这样可以回答所有询问,时间复杂度 $ O(p log(R_0 − L_0)) $ 。如果 $ r − l $ 不是很大,那么也可以用 $ O((| Q |) + O(r − l) )$ 的时间将序列分成两部分,总复杂度为 $ O( (p + R_0 − L_0) log(R_0 − L_0) ) $。
有些路你和某人一起走,就长得离谱,你和另外一些人走,就短得让人舍不得迈开脚步。