[Luo Gu P1712] NOI2016 range

Problem Description

On the number line with n closed interval [l1, r1], [l2, r2], ..., [ln, rn]. Now selected from m intervals, so that these m interval comprises at least one common position. In other words, so that there is an x, such that for each selected interval [li, ri], there li≤x≤ri.

For the selection of a legitimate program, its cost minus the selected minimum interval length is selected longest interval length. Interval [li, ri] is defined as the length ri-li, i.e., a value equal to its right end point minus the value of the left point.

Input Format

The first line contains two positive integers n, m separated by a space, meaning as described above. Ensure 1≤m≤n

Subsequently n rows, each row represents a section, separated by a space containing the left and right end points of two integers ri and li for the interval.

N<=500000,M<=200000,0≤li≤ri≤10^9

Output Format

Only one line containing a positive integer that is the minimum cost.

Sample input

6 3
3 5
1 2
3 4
2 2
1 5
1 4

Sample Output

2

Explanation

img

img

Resolve

Where possible, we want to take a small fee range, so put all the sections by length from small to large. Borrowing the idea of ​​using the ruler, joined by one interval. If the number of times a time greater than a point covered m, statistics answer, then began until removed from the front cover section number is less than m. Specific maintenance cover can maintain a maximum number of times to do with the segment tree. Of course, l and r to discretization.

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#define N 500002
using namespace std;
struct seg{
    int len,l,r;
}a[N];
struct SegmentTree{
    int dat,add;
}t[N*8];
int n,m,i,j,tmp[N*2];
int read()
{
    char c=getchar();
    int w=0;
    while(c<'0'||c>'9') c=getchar();
    while(c<='9'&&c>='0'){
        w=w*10+c-'0';
        c=getchar();
    }
    return w;
}
int my_comp(const seg &x,const seg &y)
{
    return x.len<y.len;
}
void spread(int p)
{
    if(t[p].add){
        t[p*2].dat+=t[p].add;
        t[p*2+1].dat+=t[p].add;
        t[p*2].add+=t[p].add;
        t[p*2+1].add+=t[p].add;
        t[p].add=0;
    }
}
void change(int p,int l,int r,int ql,int qr,int x)
{
    if(ql<=l&&r<=qr){
        t[p].dat+=x;
        t[p].add+=x;
        return;
    }
    int mid=(l+r)/2;
    spread(p);
    if(ql<=mid) change(p*2,l,mid,ql,qr,x);
    if(qr>mid) change(p*2+1,mid+1,r,ql,qr,x);
    t[p].dat=max(t[p*2].dat,t[p*2+1].dat);
}
int main()
{
    n=read();m=read();
    for(i=1;i<=n;i++){
        a[i].l=read(),a[i].r=read();
        tmp[i*2-1]=a[i].l;
        tmp[i*2]=a[i].r;
    }
    sort(tmp+1,tmp+2*n+1);
    int n1=unique(tmp+1,tmp+2*n+1)-tmp-1;
    for(i=1;i<=n;i++){
        a[i].len=a[i].r-a[i].l;
        a[i].l=lower_bound(tmp+1,tmp+n1+1,a[i].l)-tmp;
        a[i].r=lower_bound(tmp+1,tmp+n1+1,a[i].r)-tmp;
    }
    sort(a+1,a+n+1,my_comp);
    i=j=0;
    int ans=1<<30;
    while(i<n){
        while(i<n&&t[1].dat<m){
            i++;
            change(1,1,n1,a[i].l,a[i].r,1);
        }
        if(t[1].dat<m) break;
        while(j<n&&t[1].dat>=m){
            j++;
            change(1,1,n1,a[j].l,a[j].r,-1);
        }
        ans=min(ans,a[i].len-a[j].len);
    }
    if(ans==1<<30) printf("-1\n");
    else printf("%d\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/LSlzf/p/11876800.html