BZOJ4653: [Noi2016]区间

原来这么做叫尺取,,,涨姿势了

就是维护两个指针,r 一直扩大直到符合要求

然后将 l 指针向着不断缩小这个区间的方向,直到不符合要求

那么最后删掉的位置到 r 就是一个符合要求的极小区间

不断重复上述过程就能找出最小的

这题就是这么做,线段树维护 max,检查是否符合要求


 代码:

#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cctype>
#define lson (x << 1)
#define rson ((x << 1) | 1)
using namespace std;

const int MAXN = 500005, MAXM = 200005;

struct INTERVAL{
	int l, r, ul, ur;
	bool operator < (const INTERVAL& b) const {
		return (r - l) < (b.r - b.l);
	}
}itv[MAXN];
struct Node{
	int maxn, lzy;
}t[MAXN << 3];
int n, m, sizu, ans = 2147483647;
int uni[MAXN << 1];

inline int rd() {
	register int x = 0;
	register char c = getchar();
	while(!isdigit(c)) c = getchar();
	while(isdigit(c)) {
		x = x * 10 + (c ^ 48);
		c = getchar();
	}
	return x;
}
inline void pushup(int x) {
	t[x].maxn = max(t[lson].maxn, t[rson].maxn);
	return;
}
inline void pushdown(int x) {
	register int lzy = t[x].lzy;
	t[x].lzy = 0;
	t[lson].lzy += lzy;
	t[lson].maxn += lzy;
	t[rson].lzy += lzy;
	t[rson].maxn += lzy;
	return;
}
void update(int L, int R, int l, int r, int x, int val) {
	if(L <= l && r <= R) {
		t[x].lzy += val;
		t[x].maxn += val;
		return;
	}
	if(t[x].lzy) pushdown(x);
	int mid = ((l + r) >> 1);
	if(L <= mid) update(L, R, l, mid, lson, val);
	if(mid < R) update(L, R, mid + 1, r, rson, val);
	pushup(x);
	return;
}

int main() {
	n = rd(); m = rd();
	for(int i = 1; i <= n; ++i) {
		itv[i].l = rd(); itv[i].r = rd();
		uni[++sizu] = itv[i].l;
		uni[++sizu] = itv[i].r;
	}
	sort(uni + 1, uni + sizu + 1);
	sizu = unique(uni + 1, uni + sizu + 1) - uni - 1;
	sort(itv + 1, itv + n + 1);
	for(int i = 1; i <= n; ++i) {
		itv[i].ul = lower_bound(uni + 1, uni + sizu + 1, itv[i].l) - uni;
		itv[i].ur = lower_bound(uni + 1, uni + sizu + 1, itv[i].r) - uni;
	}
	int l = 0, r = 0;
	bool GG = false;
	while(r < n) {
		while(r < n && t[1].maxn < m) {
			++r;
			update(itv[r].ul, itv[r].ur, 1, sizu, 1, 1);
		}
		GG = (t[1].maxn < m);
		while(l <= r && t[1].maxn >= m) {
			++l;
			update(itv[l].ul, itv[l].ur, 1, sizu, 1, -1);
		}
		if(!GG) ans = min(ans, (itv[r].r - itv[r].l) - (itv[l].r - itv[l].l));
	}
	printf("%d\n", (ans == 2147483647 ? -1 : ans));
	return 0;
}
posted @ 2018-10-12 20:18  EvalonXing  阅读(120)  评论(0编辑  收藏  举报