E. Boring Segments
题意
有一个大区间 [1,m],给定 n 个小区间
每个小区间范围是 [li,ri](1⩽li<ri⩽m),每个小区间还有一个权值 wi
定义两个区间中的点可以相互到达,当且仅当,两个区间存在交集,如 [1,3],[3,4] 连通,而 [1,3],[4,5] 不连通
定义一个子集的花费为:该子集中的最大的权值-最小的权值
现在求一个子集使得在区间 [1,m] 中的任意两个点都可以相互到达,且花费最少
思路
最一开始想了半天二分答案,发现check函数不好写
看了题解后,发现可以直接通过双指针的方法,对区间的权值进行查询
双指针的方法,一般用于求一个连续的区间,并且右端点关于左端点单调递增
这道题如果将区间按权值,从小到大排序,我们发现它其实是满足使用双指针条件的
当左端点是 l 时,我们令:f(l) 为最小的满足条件的右端点位置
我们用反证法证明:f(x) 是单增的,若 ∃x<x+1,f(x)>f(x+1)
由于集合区间 [x+1,f(x+1)] 是满足题目要求的
那么集合区间 x∩[x+1,f(x+1)]=[x,f(x+1)] 一定也是满足题目要求的
那么一定有 f(x)⩽f(x+1) 与 f(x)>f(x+1) 矛盾,则 f(x) 一定单增
判断一个区间 [1,m] 中的任意两点是否能互相到达,我是直接把数域扩大2倍后,用线段树判断是否能完全覆盖 [2,2m] 的,不过感觉标程好像更简单
如 [1,3],[3,4]⟺[2,6]∩[6,8]={6} yes,[1,2],[3,4]⟺[2,4]∩[6,8]=∅ no
总复杂度 O(MlogM+NlogM)
点击显/隐代码