zoukankan      html  css  js  c++  java
  • 区间(bzoj 4653)

    Description

    在数轴上有 n个闭区间 [l1,r1],[l2,r2],...,[ln,rn]。现在要从中选出 m 个区间,使得这 m个区间共同包含至少一个位置。换句话说,就是使得存在一个 x,使得对于每一个被选中的区间 [li,ri],都有 li≤x≤ri。
     
    对于一个合法的选取方案,它的花费为被选中的最长区间长度减去被选中的最短区间长度。区间 [li,ri] 的长度定义为 ri−li,即等于它的右端点的值减去左端点的值。
     
    求所有合法方案中最小的花费。如果不存在合法的方案,输出 −1。

    Input

    第一行包含两个正整数 n,m用空格隔开,意义如上文所述。保证 1≤m≤n
     
    接下来 n行,每行表示一个区间,包含用空格隔开的两个整数 li 和 ri 为该区间的左右端点。
    N<=500000,M<=200000,0≤li≤ri≤10^9

    Output

    只有一行,包含一个正整数,即最小花费。

    Sample Input

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

    Sample Output

    2
    /*
        不得不说,本弱是真弱啊,这道题的思路好像不是很难,但是就是想不出。
        首先将区间离散化,然后按照区间长度排序,一种暴力的方法是枚举左区间,然后枚举用线段树判定找到第一个满足条件的右区间,这样的方法是O(n^2logn)的。
        其实我们可以发现对于递增的左区间来说,第一个满足条件的右区间也是递增的,这样复杂度就降到了O(nlogn)。 
    */
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define N 500010
    #define inf 1000000000
    using namespace std;
    int b[N*2],n,m;
    int mx[N*8],tag[N*8];
    struct node{int l,r,len;}a[N];
    bool cmp(const node&x,const node&y){return x.len<y.len;}
    
    void push_up(int k){
        mx[k]=max(mx[k*2],mx[k*2+1]);
    }
    void push_down(int k){
        if(!tag[k]) return;
        mx[k*2]+=tag[k];
        tag[k*2]+=tag[k];
        mx[k*2+1]+=tag[k];
        tag[k*2+1]+=tag[k];
        tag[k]=0;
    }
    void add(int k,int l,int r,int x,int y,int val){
        if(l>=x&&r<=y){
            mx[k]+=val;
            tag[k]+=val;
            return;
        }
        push_down(k);
        int mid=l+r>>1;
        if(x<=mid) add(k*2,l,mid,x,y,val);
        if(y>mid) add(k*2+1,mid+1,r,x,y,val);
        push_up(k);
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&a[i].l,&a[i].r);
            a[i].len=a[i].r-a[i].l;
            b[i*2-1]=a[i].l;
            b[i*2]=a[i].r;
        }
        sort(b+1,b+n*2+1);
        int tot=unique(b+1,b+2*n+1)-b-1;
        for(int i=1;i<=n;i++){
            a[i].l=lower_bound(b+1,b+tot+1,a[i].l)-b;
            a[i].r=lower_bound(b+1,b+tot+1,a[i].r)-b;
        }
        sort(a+1,a+n+1,cmp);
        int tt=1,ans=inf;
        for(int i=1;i<=n;i++){
            while(mx[1]<m&&tt<=n){
                add(1,1,tot,a[tt].l,a[tt].r,1);
                tt++;
            }
            if(mx[1]>=m) ans=min(ans,a[tt-1].len-a[i].len);
            add(1,1,tot,a[i].l,a[i].r,-1);
        }
        if(ans!=inf) printf("%d",ans);
        else printf("-1");
        return 0;
    }
  • 相关阅读:
    javascript的语法作用域你真的懂了吗
    网页的三种布局(固定宽度式,流体式,弹性式)
    css3系列之animation
    跟我学习css3之transition
    函数调用你知道几种方法
    javascript的那些事儿你都懂了吗
    css3的那些高级选择器二
    [转]影响Cache的几个HTTP头信息
    CSS属性合写
    defer 与 async
  • 原文地址:https://www.cnblogs.com/harden/p/6766759.html
Copyright © 2011-2022 走看看