题目描述
我们可以发现对于最优解的被m次覆盖的某个位置一定是某一个线段的端点,故离散化。
先将所有区间按照区间长度排序。
我们可以发现对于最优解一定出现在排序后的连续区间内。
比如若对于最优解需要排序后的第一个区间与第三个区间,那么此时如果加上第二个区间,那么最优解的值也是一样的。
那么维护两个指针l和r,用线段树对区间作区间覆盖,用尺取法求解。
#include<bits/stdc++.h>
#define fer(i,j,n) for(int i=j;i<=n;i++)
#define far(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define pa pair<int,int>
const int maxn=4000010;
const int INF=1e9+7;
using namespace std;
/*----------------------------------------------------------------------------*/
inline ll read()
{
char ls;ll x=0,sng=1;
for(;ls<'0'||ls>'9';ls=getchar())if(ls=='-')sng=-1;
for(;ls>='0'&&ls<='9';ls=getchar())x=x*10+ls-'0';
return x*sng;
}
/*----------------------------------------------------------------------------*/
int n,m,cnt,ans=INF;
int b[maxn];
struct kaga
{
int l,r,maxx,lazy;
}tr[maxn];
struct akagi
{
int l,r,len;
bool friend operator <(akagi a,akagi b)
{
return a.len<b.len;
}
}a[maxn];
void maxup(int x)
{
tr[x].maxx=max(tr[x<<1].maxx,tr[x<<1|1].maxx);
}
void pushdown(int x)
{
if(tr[x].lazy)
{
tr[x<<1].lazy+=tr[x].lazy;
tr[x<<1].maxx+=tr[x].lazy;
tr[x<<1|1].lazy+=tr[x].lazy;
tr[x<<1|1].maxx+=tr[x].lazy;
tr[x].lazy=0;
}
return ;
}
void build(int x,int l,int r)
{
int mid=(l+r)>>1;
tr[x].l=l;tr[x].r=r;
if(l==r)
{
tr[x].maxx=0;
return ;
}
build(x<<1,l,mid);
build(x<<1|1,mid+1,r);
maxup(x);
}
void change(int x,int L,int R,int val)
{
int l=tr[x].l,r=tr[x].r,mid=(l+r)>>1;
if(l>=L&&r<=R)
{tr[x].lazy+=val;tr[x].maxx+=val;return ;}
pushdown(x);
if(R<=mid)change(x<<1,L,R,val);
else if(L>mid)change(x<<1|1,L,R,val);
else change(x<<1,L,mid,val),change(x<<1|1,mid+1,R,val);
maxup(x);
}
int main()
{
cnt=0;
n=read();m=read();
fer(i,1,n)
{
a[i].l=read();a[i].r=read();a[i].len=a[i].r-a[i].l;
b[++cnt]=a[i].l;b[++cnt]=a[i].r;
}
if(m==1)ans=0;
sort(a+1,a+n+1);
sort(b+1,b+cnt+1);
cnt=unique(b+1,b+cnt+1)-b-1;
build(1,1,cnt);
fer(i,1,n)
{
a[i].l=lower_bound(b+1,b+cnt+1,a[i].l)-b;
a[i].r=lower_bound(b+1,b+cnt+1,a[i].r)-b;
}
int l=1,r=0;
while(l<=n)
{
while(tr[1].maxx<m)
{
if(r==n)
{
if(ans==INF)cout<<-1<<endl;
else cout<<ans<<endl;
return 0;
}
r++;
change(1,a[r].l,a[r].r,1);
}
ans=min(ans,a[r].len-a[l].len);
change(1,a[l].l,a[l].r,-1);
l++;
}
cout<<ans<<endl;
}