将所有区间按li-ri排序,那么答案一定是一段连续的区间
有单调性,两个指针扫
一段区间是合法的当且仅当这个区间中存在一个点被超过m个区间覆盖
线段树维护区间最大值,支持区间加法操作即可
notice:l,r达到了1e9,需要离散化
/**************************************************************
Problem: 4653
User: di4CoveRy
Language: C++
Result: Accepted
Time:9464 ms
Memory:67700 kb
****************************************************************/
#include <iostream>
#include <cstdio>
#include <algorithm>
#define N 1000050
#define mid ( (l + r) >> 1 )
#define ls l,mid,t<<1
#define rs mid+1,r,t<<1^1
using namespace std;
struct Monster{ int l,r,w; }Q[N];
bool operator <(Monster p1,Monster p2) { return p1.w < p2.w; }
int tr[4*N],ag[4*N];
int d[2*N],e[2*N],a[2*N];
int ll,rr,v,tp,ans,n,m;
bool cmp(int p1,int p2) { return d[p1] < d[p2]; }
inline void ut(int &x,int y) { x = min(x,y); }
void push_down(int t) {
ag[t<<1] += ag[t]; ag[t<<1^1] += ag[t];
tr[t<<1] += ag[t]; tr[t<<1^1] += ag[t];
ag[t] = 0; return ;
}
void update(int l,int r,int t ){
if (l > rr || r < ll) return ;
if (l >= ll && r <= rr) {
tr[t] += v; ag[t] += v; return;
}
push_down(t); update(ls); update(rs);
tr[t] = max(tr[t<<1],tr[t<<1^1]);
}
int main() {
scanf("%d%d",&n,&m);
for (int _=1;_<=n;_++) {
scanf("%d%d",&Q[_].l,&Q[_].r);
Q[_].w = Q[_].r - Q[_].l;
d[2*_-1] = Q[_].l , d[2*_] = Q[_].r;
}
//ÀëÉ¢»¯
for (int i=1;i<=2*n;i++) e[i] = i;
sort(e+1,e+2*n+1,cmp);
for (int i=1;i<=2*n;i++)
a[ e[i] ] = d[ e[i] ] == d[ e[i-1] ] ? a[ e[i-1] ] : a[ e[i-1] ] + 1;
for (int i=1;i<=n;i++) Q[i].l = a[2*i-1] , Q[i].r = a[2*i];
tp = a[ e[2*n] ];
sort(Q+1,Q+n+1);
int h = 1 , t = 0;
while (tr[1] < m && t < n) {
++t;
ll = Q[t].l , rr = Q[t].r , v = 1;
update(1,tp,1);
}
ans = 1<<30;
if (tr[1] >= m) ut(ans, Q[t].w-Q[1].w );
while (t < n) {
ll = Q[h].l , rr = Q[h].r , v = -1;
update(1,tp,1);
h++;
while (tr[1] < m && t+1 <= n) {
t++;
ll = Q[t].l , rr = Q[t].r , v = 1;
update(1,tp,1);
}
if (tr[1] >= m) ut(ans , Q[t].w-Q[h].w);
}
if (ans == (1<<30)) ans = -1;
printf("%d\n",ans);
return 0;
}