[NOI2016]区间
链接:https://www.luogu.org/problemnew/show/P1712
题解:
显然是个滑动窗口的问题,用线段树维护最大值即可
注意:离散化时空间要开2倍,最大值初始赋值为2e9比较好
代码:
#include <bits/stdc++.h>
using namespace std;
#define maxn 500100
#define mm 1999999999
#define lll long long
lll n,m;
struct re{
lll a,b,len,c,d;
}a[maxn],b[maxn*2];
bool cmp(re x,re y)
{
if (x.len>y.len) return(true); else return(false);
}
struct ree
{
lll h,t,x,lazy;
}p[maxn*4];
void updata(lll x)
{
p[x].x=max(p[x*2].x,p[x*2+1].x);
}
#define mid (h+t)/2
void build(lll x,lll h,lll t)
{
p[x].h=h; p[x].t=t;
p[x].x=0; p[x].lazy=0;
if (h==t) return;
build(x*2,h,mid); build(x*2+1,mid+1,t);
}
void down(lll x)
{
if (p[x].lazy)
{
p[x].x+=p[x].lazy;
if (p[x].h!=p[x].t)
{
p[x*2].lazy+=p[x].lazy;
p[x*2+1].lazy+=p[x].lazy;
}
p[x].lazy=0;
}
}
void change (lll x,lll h,lll t,lll sum)
{
down(x);
if (p[x].h>t||p[x].t<h) return;
if (h<=p[x].h&&p[x].t<=t)
{
p[x].lazy+=sum; down(x);
return;
}
change(x*2,h,t,sum);change(x*2+1,h,t,sum);
updata(x);
}
lll query(lll x,lll h,lll t)
{
down(x);
if (p[x].h>t||p[x].t<h) return(0);
if (h<=p[x].h&&p[x].t<=t)
{
return(p[x].x);
}
return(max(query(x*2,h,t),query(x*2+1,h,t)));
}
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for (lll i=1;i<=n;i++)
{
cin>>a[i].a>>a[i].b;
a[i].len=a[i].b-a[i].a;
}
sort(a+1,a+1+n,cmp);
for (lll i=1;i<=n;i++)
{
b[i*2-1].a=i*2-1; b[i*2].a=i*2;
b[i*2-1].len=a[i].a; b[i*2].len=a[i].b;
}
sort(b+1,b+2*n+1,cmp);
lll ll=0; b[0].len=-mm;
for (lll i=1;i<=2*n;i++)
{
if (b[i].len!=b[i-1].len) ll++;
if (b[i].a%2==0) a[(b[i].a-1)/2+1].c=ll;
else a[(b[i].a-1)/2+1].d=ll;
}
build(1,1,ll);
lll h=0,t=0;
lll ans=mm;
//for (lll i=1;i<=2*n;i++) cout<<b[i].len<" ";
//for (lll i=1;i<=n;i++) cout<<endl<<a[i].a<<" "<<a[i].b<<" "<<a[i].c<<" "<<a[i].d;
while (t<n)
{
h++;
if (h!=1)
{
change(1,a[h-1].c,a[h-1].d,-1);
}
while (query(1,1,ll)<m&&t<=n)
{
t++; change(1,a[t].c,a[t].d,1);
}
if (t<=n) ans=min(ans,a[h].len-a[t].len);
}
if (ans!=mm)cout<<ans; else cout<<-1;
}