BZOJ_4653_[Noi2016] Interval _ segment tree + discretization + double pointer

BZOJ_4653_[Noi2016] Interval _ segment tree + discretization + double pointer

Description

There are n closed intervals [l1,r1],[l2,r2],...,[ln,rn] on the number line. Now m intervals are to be selected such that the m intervals collectively contain at least one position. In other words, there is an x ​​such that for each selected interval [li,ri], li≤x≤ri.
For a valid selection scheme, its cost is the length of the longest interval chosen minus the length of the shortest interval chosen. The length of the interval [li,ri] is defined as ri−li, which is equal to the value of its right endpoint minus the value of its left endpoint.
Find the smallest cost among all legal alternatives. If no valid solution exists, output −1.

Input

The first line contains two positive integers n, m separated by spaces, meaning as described above. Guaranteed 1≤m≤n
Next n lines, each line represents an interval, including two integers li and ri separated by spaces as the left and right endpoints of the interval.
N<=500000,M<=200000,0≤li≤ri≤10^9

Output

There is only one line containing a positive integer, the minimum cost.

Sample Input

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

Sample Output

2

Sort the ranges by length.
It can be found that my choice of an interval of a continuous interval will not make the answer worse. And legally the two endpoints are monotonic.
So you can scan it with two pointers, determine the legal shortest interval each time, and update the answer.
Each time adding/deleting an interval is equivalent to interval addition/subtraction, and the operation of finding the maximum value of the interval can be realized by using a line segment tree.
The interval needs to be discretized, and only the left and right endpoints are useful.
 
Code:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 500050
#define ls p<<1
#define rs p<<1|1
int n,m,turn[N<<1],maxn;
int t[N<<3],add[N<<3];
struct A {
    int l,r,lx,rx;
}q[N];
bool cmp1(const A &x,const A &y) {return x.r-x.l<y.r-y.l;}
int p[N<<1];
inline void pushup(int p) {
    t[p]=max(t[ls],t[rs]);
}
inline void pushdown(int p) {
    int d;
    if(d=add[p]) {
        t[ls]+=d; t[rs]+=d;
        add[ls]+=d; add[rs]+=d;
        add[p]=0;
    }
}
void update(int l,int r,int x,int y,int v,int p) {
    if(x<=l&&y>=r) {
        t[p]+=v; add[p]+=v;
        return ;
    }
    pushdown(p);
    int mid=(l+r)>>1;
    if(x<=mid) update(l,mid,x,y,v,ls);
    if(y>mid) update(mid+1,r,x,y,v,rs);
    pushup(p);
}
int query (int l, int r, int x, int y, int p) {
    if(x<=l&&y>=r) return t[p];
    pushdown(p);
    int mid=(l+r)>>1,re=0;
    if(x<=mid) re=max(re,query(l,mid,x,y,ls));
    if(y<mid) re=max(re,query(mid+1,r,x,y,rs));
    pushup(p);
    return re;
}
int main() {
    scanf("%d%d",&n,&m);
    int i,x,y;
    for(i=1;i<=n;i++) {
        scanf("%d%d",&q[i].l,&q[i].r);
        p[i]=q[i].l,p[i+n]=q[i].r;
    }
    sort(p+1,p+2*n+1);
    int j=0;p[0]=5343453;
    for(i=1;i<=n;i++) {
        q[i].lx=lower_bound(p+1,p+n+n+1,q[i].l)-p;
        q[i].rx=lower_bound(p+1,p+n+n+1,q[i].r)-p;
    }
    maxn=2*n;
    sort(q+1,q+n+1,cmp1);
    //for(i=1;i<=n;i++) printf("%d %d\n",turn[q[i].l],turn[q[i].r]);
    int l=1,r=0,ans=1<<30;
    while(r<n) {
        while(t[1]<m&&r<n) r++,update(1,maxn,q[r].lx,q[r].rx,1,1);
        if(t[1]<m) break;
        while(t[1]>=m&&l<n) update(1,maxn,q[l].lx,q[l].rx,-1,1),l++;
        ans=min(ans,q[r].r-q[r].l-q[l-1].r+q[l-1].l);
    }
    printf("%d\n",ans<(1<<30)?ans:-1);
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325332075&siteId=291194637