bzoj4653: [Noi2016]区间
[TOC]
#题目链接
bzoj4653: [Noi2016]区间
#题解
区间长度排序后维护一个满足m条件的滑动区间
#代码
#include<cstdio>
#include<vector>
#include<algorithm>
#define gc getchar()
#define pc putchar
#define LL long long
#define pb push_back
inline int read() {
int x = 0,f = 1;
char c = gc;
while(c < '0' || c > '9')c = gc;
while(c <= '9' && c >= '0') x = x * 10 + c -'0',c = gc;
return x * f;
}
void print(LL x) {
if(x < 0) {
pc('-'); x = -x;
}
if(x >= 10) print(x / 10);
pc(x % 10 + '0');
}
const int maxn = 500007;
struct ZZX {
int l,r,len;
bool operator < (const ZZX &a) const {
return len < a.len;
}
} a[maxn];
int n,m;
int b[maxn << 1];
int t[(maxn * 2) << 2],tag[(maxn * 2) << 2];
#define ls x << 1,l,mid
#define rs x << 1 | 1,mid + 1,r
void modify(int x,int l,int r,int L,int R,int k) {
if(l >= L && r <= R) {
t[x] += k;
tag[x] += k;
return;
}
int mid = l + r >> 1;
if(tag[x] != 0) {
t[x << 1] += tag[x];
t[x << 1 | 1] += tag[x];
tag[x << 1] += tag[x];
tag[x << 1 | 1] += tag[x];
tag[x] = 0;
}
if(L <= mid) modify(ls,L,R,k);
if(R > mid) modify(rs,L,R,k);
t[x] = std::max(t[x << 1],t[x << 1 | 1]);
}
int main() {
//freopen("11.in","r",stdin);
n = read(); m = read();
int tot = 0;
for(int i = 1;i <= n;++ i)
a[i].l = read(),a[i].r = read(),
a[i].len = a[i].r - a[i].l + 1,
b[ ++ tot] = a[i].l,b[++ tot] = a[i].r;
std::sort(b + 1,b + tot + 1);
tot = std::unique(b + 1,b + tot + 1) - b - 1;
for(int i = 1;i <= n;++ i)
a[i].l = std::lower_bound(b + 1,b + tot + 1,a[i].l) - b,
a[i].r = std::lower_bound(b + 1,b + tot + 1,a[i].r) - b;
std::sort(a + 1,a + n + 1);
#define INF 0x3f3f3f3f
int ans = INF;
for(int l = 1,r = 1;r <= n;++ r) {
while(t[1] < m && r <= n) {
modify(1,1,tot,a[r].l,a[r].r,1);
++ r;
}
if(t[1] < m) break;
-- r;
while(t[1] >= m) modify(1,1,tot,a[l].l,a[l].r,-1) , ++ l;
ans = std::min(ans,a[r].len - a[l - 1].len);
}
print(ans == INF ? -1 : ans);
return 0;
}