NOI2016区间
在数轴上有$ n $个闭区间 $[l_1,r_1],[l_2,r_2],…,[l_n,r_n]$。现在要从中选出 $m $个区间,使得这$ m $个区间共同包含至少一个位置。换句话说,就是使得存在一个 $x$,使得对于每一个被选中的区间$ [l_i,r_i]$,都有 $l_i≤x≤r_i$。
对于一个合法的选取方案,它的花费为被选中的最长区间长度减去被选中的最短区间长度。区间$ [l_i,r_i] $的长度定义为$ r_i−l_i$,即等于它的右端点的值减去左端点的值。
求所有合法方案中最小的花费。如果不存在合法的方案,输出 $−1$。
输入格式
第一行包含两个正整数$ n,m$,用空格隔开,意义如上文所述。保证$ 1≤m≤n$。
接下来 $n$行,每行表示一个区间,包含用空格隔开的两个整数 $l_i $和 $r_i$ 为该区间的左右端点。
输出格式
只有一行,包含一个正整数,即最小花费。
样例
input
6 3
3 5
1 2
3 4
2 2
1 5
1 4
output
2
数据范围与约定
$ n<=500000,m<=200000$
时间限制:3s
空间限制:256MB
题解
这题暴力还是很好打的,$O(n^2logn)$+离散化可以水过去60分。具体就是枚举重叠的是哪一个点然后暴力计算出哪些区间可以选,然后排序贪心地选连续的$m$个即可。
正解是用线段树维护。离散化之后,将区间按长度排序,我们可以发现在选择的时候,枚举一个最小和一个最大,即一个左指针,一个右指针,然后可以发现,我们可以用线段树维护每个点被几个区间覆盖了,然后对于线段树维护的全局最大值,如果当前大于$m$,则可以直接在当前选的区间范围内的右端点减去左端点就是当前的$ans$,持续更新即可。
复杂度$O(nlogn)$。
code
|
|