[题目链接]
https://www.lydsy.com/JudgeOnline/problem.php?id=4653
[算法]
首先将区间按长度排序
那么 , 满足条件的一定是一段连续的区间 , [Li , Ri] , [Li+1,Ri+1] ... [Lj , Rj]
我们不妨枚举每一个L , 不难发现当L递增时 , 满足条件的 , 最小的R同样是单调递增的 , 不妨用Two-Pointers计算这个最小的R并更新答案
我们还需用线段树维护当前被覆盖最多次的位置被覆盖了多少次
由于每个位置都会被访问并更新一次 , 故时间复杂度为 : O(NlogN)
[代码]
#include<bits/stdc++.h> using namespace std; #define MAXN 500010 #define MAXM 200010 const int inf = 2e9; struct range { int l , r; } a[MAXN]; int n , m , len; int tmp[MAXN << 1] , l[MAXN] , r[MAXN]; struct Segment_Tree { struct Node { int l , r; int mx , tag; } Tree[MAXN << 4]; inline void build(int index , int l , int r) { Tree[index].l = l; Tree[index].r = r; Tree[index].mx = Tree[index].tag = 0; if (l == r) return; int mid = (l + r) >> 1; build(index << 1 , l , mid); build(index << 1 | 1 , mid + 1 , r); } inline void pushdown(int index) { Tree[index << 1].mx += Tree[index].tag; Tree[index << 1 | 1].mx += Tree[index].tag; Tree[index << 1].tag += Tree[index].tag; Tree[index << 1 | 1].tag += Tree[index].tag; Tree[index].tag = 0; } inline void update(int index) { Tree[index].mx = max(Tree[index << 1].mx , Tree[index << 1 | 1].mx); } inline void modify(int index , int l ,int r , int value) { if (Tree[index].l == l && Tree[index].r == r) { Tree[index].mx += value; Tree[index].tag += value; return; } pushdown(index); int mid = (Tree[index].l + Tree[index].r) >> 1; if (mid >= r) modify(index << 1 , l , r , value); else if (mid + 1 <= l) modify(index << 1 | 1 , l , r , value); else { modify(index << 1 , l , mid , value); modify(index << 1 | 1 , mid + 1 , r , value); } update(index); } inline int query() { return Tree[1].mx; } } SGT; template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); } template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); } template <typename T> inline void read(T &x) { T f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } inline bool cmp(range a , range b) { return a.r - a.l < b.r - b.l; } int main() { read(n); read(m); for (int i = 1; i <= n; i++) { read(a[i].l); read(a[i].r); tmp[i * 2 - 1] = a[i].l; tmp[i * 2] = a[i].r; } sort(tmp + 1 , tmp + 2 * n + 1); len = unique(tmp + 1 , tmp + 2 * n + 1) - tmp - 1; sort(a + 1 , a + n + 1 , cmp); for (int i = 1; i <= n; i++) { l[i] = lower_bound(tmp + 1 , tmp + len + 1 , a[i].l) - tmp; r[i] = lower_bound(tmp + 1 , tmp + len + 1 , a[i].r) - tmp; } SGT.build(1 , 1 , len); int ans = inf , rgt = 0; for (int i = 1; i <= n; i++) { bool flg = false; while (rgt <= n) { if (SGT.query() >= m) { flg = true; break; } ++rgt; if (rgt > n) break; SGT.modify(1 , l[rgt] , r[rgt] , 1); } if (flg) chkmin(ans , (tmp[r[rgt]] - tmp[l[rgt]]) - (tmp[r[i]] - tmp[l[i]])); else break; SGT.modify(1 , l[i] , r[i] , -1); } printf("%d " , ans != inf ? ans : -1); return 0; }