Analysis
首先对坐标离散化,注意预先存储原长度
考虑对长度从小到大排序,然后(2 Pointers)扫描,右端不断加入区间并覆盖相应长度,当某一时刻存在点被覆盖(m)次时更新答案,并同时移动左指针(左端在移动的过程中可能有多次更新答案的机会)到第一个不满足被覆盖(m)次的区间
由于先前对坐标进行了离散化,对点被覆盖次数的维护用线段树进行,区间加区间(max)
Code
#include<bits/stdc++.h>
using namespace std;
inline int read() {
int cnt = 0, f = 1; char c = getchar();
while (!isdigit(c)) {if (c == '-') f = -f; c = getchar();}
while (isdigit(c)) {cnt = (cnt << 3) + (cnt << 1) + (c ^ 48); c = getchar();}
return cnt * f;
}
const int N = 5 * (int)1e5 + 10;
const int INF = (int)1e9 + 7;
int n, m, pos = 1;
int b[N << 1], tot, ans = INF, q;
struct node {
int l, r;
int tag, gmax;
#define l(p) tree[p].l
#define r(p) tree[p].r
#define tag(p) tree[p].tag
#define gmax(p) tree[p].gmax
#define ls p << 1
#define rs p << 1 | 1
}tree[N << 4];
struct node2 {
int l, r;
int len;
}a[N];
bool cmp(node2 a, node2 b) {
return a.len < b.len;
}
void pushup(int p) {gmax(p) = max(gmax(ls), gmax(rs));}
void pushadd(int p, int d) {tag(p) += d, gmax(p) += d;}
void pushdown(int p) {if (tag(p)) pushadd(ls, tag(p)), pushadd(rs, tag(p)), tag(p) = 0;}
void build(int p, int l, int r) {
l(p) = l, r(p) = r;
if (l == r) {gmax(p) = 0; return;}
int mid = (l + r) >> 1;
build(ls, l, mid);
build(rs, mid + 1, r);
pushup(p);
}
void modify(int p, int l, int r, int d) {
// cout << p << ' ' << l(p) << ' ' << r(p) << endl;
if (l <= l(p) && r >= r(p)) {pushadd(p, d); return;}
pushdown(p);
int mid = (l(p) + r(p)) >> 1;
if (l <= mid) modify(ls, l, r, d);
if (r > mid) modify(rs, l, r, d);
pushup(p);
}
void init() {
sort (b + 1, b + tot + 1);
q = unique(b + 1, b + tot + 1) - b - 1;
for (register int i = 1; i <= n; ++i) a[i].l = lower_bound(b + 1, b + q + 1, a[i].l) - b;
for (register int i = 1; i <= n; ++i) a[i].r = lower_bound(b + 1, b + q + 1, a[i].r) - b;
}
int main() {
// freopen("1.in", "r", stdin);
n = read(), m = read();
for (register int i = 1; i <= n; ++i) a[i].l = read(), a[i].r = read(), a[i].len = a[i].r - a[i].l, b[++tot] = a[i].l, b[++tot] = a[i].r;
init();
sort (a + 1, a + n + 1, cmp);
build(1, 1, q);
for (register int i = 1; i <= n; ++i) {
modify(1, a[i].l, a[i].r, 1);
while (gmax(1) >= m && pos < i) ans = min(ans, (a[i].len - a[pos].len)), modify(1, a[pos].l, a[pos].r, -1), ++pos;
} printf(ans == INF ? "-1" : "%d", ans);
return 0;
}