P1712 [NOI2016] 区间 题解

思考

我们考虑枚举最长的长度.

然后假设我们目前最长的长度为\(len_{max}\),那么我们就要找最大的\(len_{min}\),使得存在一个点,使得至少有\(m\)个长度在\([len_{min},len_{max}]\)中的线段个将这个点覆盖.

覆盖可以使用线段树维护.

那么我们枚举长度的时间复杂度是\(O(n)\) 的,我们枚举最小长度的复杂度是\(O(n)\)的,对于每个线段使用线段树维护区间覆盖的复杂度是\(O(nlogn)\)的.

那么我们总的复杂度就是\(O(n(n+nlogn))\) 的.这显然太大了.

我们发现,在我们枚举\(len_{max}\)的过程中,\(len_{min}\)单调不下降.

那么我们考虑使用双指针优化.

我们维护双指针\(l,r\)代表最短长度和最长的长度,不过注意枚举的要是离散的.

然后我们考虑怎么实现判断\(l\)的增加.

问题就是判断\(l\)增加后区间最大端点覆盖会不会下降到小于\(m\).

显然,我们不能暴力的删去区间,然后恢复,那么我们就无法保证每个线段只会在线段树上删除一次.

我们考虑不恢复.

那么我们设当前实际允许的\(len_{min}\)和线段树应用的\(len_{min}\) 然后显然这两个最多差 \(1\),然后如果发现删除后不合法那就不删除,直接确定现在\(len_{max}\)的答案.

然后我们每次在尝试缩小的时候,我们先看看是否已经缩小过了,诺已经缩小过了则直接查询答案,否则缩小.

然后我们就保证了每个线段至多被插入删除一次

posted @ 2026-10-23 20:19  txp2025  阅读(5)  评论(0)    收藏  举报