yang-xi-jie-mi-zheng-ti-er-fen

详细揭秘 整体二分

考虑这样一个问题:

  • 给你一个序列,每次查询区间 kth。

如果你不会主席树,你可能会考虑二分答案:二分一个 \(mid\),看看它在区间中的 rank,与 \(k\) 比较。

这样子单次暴力是线性对数的,不太妙。问题出在哪里呢?你发现每次找 rank 是线性的,很慢。

我们把多个询问放在一起跑二分,即 整体二分,具体的:

  • 用类似二分答案的思想,确定一些询问的答案区间 \([l,r]\)。假设我们现在正在解决答案在 \([l,r]\) 内的询问。

  • 二分 \(mid=\frac{l+r}2\),将答案在 \([l,mid]\)\([mid+1,r]\) 的两类询问分开。

如何分开这两类询问?类似地,我们比较 \(mid\) 在每个询问的区间中的 rank 和这个询问的 \(k\) 的大小。

现在这个 rank 要怎么找?你想要知道在序列上一个区间 \([L,R]\) 内有多少数 \(<mid\)

注意这里只需要考虑原序列中值域在 \([l,r]\) 中的数,那么把这些数中比 \(mid\) 小的数拉出来,

将它们在序列上的位置 \(+1\),查询 \([L,R]\) 的和就是你想要的。

询问分开了,那么我们递归下去直到 \(l=r\),那么相当于二分答案结束了。注意分到右边的询问的 \(k\) 要减 rank。

这样每一层复杂度是 \(\mathcal O(n)\) 的,总复杂度为线性对数。

例题:

[POI2011]Meteors

相当于二分答案时间,看该站在这个时间前是否完成任务。

每场陨石雨相当于区间修改,每次只执行 \([l,mid]\) 的陨石雨(区间加),

检验每个站点的值是否已经满足条件即可,也就是单点查询。

[CF603E]Pastoral Oddities

原题条件等价于每个连通块大小为偶数,这里不证,不是本文重点。

随着时间推移,答案肯定越来越优,也就是答案具有单调性。维护连通块肯定是用并查集了。

考虑单次二分答案的算法。对于时间 \(i\) 的询问,我们二分一个权值 \(mid\),然后加入所有时间 \(\le i\),权值 \(\le mid\) 的边,看一下是否所有连通块都是偶数。

现在变成整体二分。分治存当前处理的时间区间 \([t_l,t_r]\) 和对应答案区间 \([w_l,w_r]\)

\(w_{mid}=\frac{w_l+w_r}2\)。考虑将时间区间拆成两部分,第一部分的答案在 \([w_{mid}+1,w_r]\) 中,另一部分答案在 \([w_l,w_{mid}]\) 中。

在进入这层分治前用并查集内维护好权值 \(<w_l\) 且时间 \(<t_l\) 的所有边。现在我们向并查集内加入权值 \(\in[w_l,w_{mid}]\),时间 \(<t_l\) 的边。

这样并查集里就有权值 \(\le w_{mid}\),时间 \(<w_l\) 的边。这和我们单次二分要求的范围很类似了,接下来继续扩展:

  • 依次加入时间 \(\in[t_l,t_r]\),权值 \(\le w_{mid}\) 的边,直到满足所有连通块都是偶数。

满足条件就可以停下来了,现在我们找到了一个分界线 \(x\),满足时间 \(\in[l,x]\) 的都没办法只用 \(\le w_{mid}\) 的边满足条件,而时间 \(\in[x+1,r]\) 的都能用 \(\le w_{mid}\) 的边满足条件。这就说明,时间 \(\in[l,x]\) 的答案都在 \([w_{mid}+1,w_r]\) 中,时间 \(\in[l,x]\) 的答案在 \([w_l,w_{mid}]\) 中。

分治下去即可。注意需要维持进入这层分治前用并查集内维护好权值 \(<w_l\) 且时间 \(<t_l\) 的所有边。

需要支持并查集的撤销,用可撤销的并查集即可。

复杂度会发现每一层加边的数量加起来都是线性,所以复杂度 \(\Theta(n\log^2n)\)

posted @ 2024-03-07 07:44  iorit  阅读(33)  评论(0)    收藏  举报