[NOI2016]区间

传送门

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;
}
posted @ 2020-05-30 14:42  kma_093  阅读(115)  评论(0编辑  收藏  举报