【NOI2016】区间(线段树+离散化)

来源:互联网 发布:黄鹤财富网络借贷 编辑:程序博客网 时间:2024/05/16 19:33

题目描述

我们可以发现对于最优解的被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;}