ccz181078

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: :: 管理 ::

Description

定义一个区间(l,r)的长度为r-l,空区间的长度为0。
给定数轴上n个区间,请选择其中恰好k个区间,使得交集的长度最大。

Input

第一行包含两个正整数n,k(1<=k<=n<=1000000),表示区间的数量。
接下来n行,每行两个正整数l,r(1<=l<r<=10^9),依次表示每个区间。

Output

第一行输出一个整数,即最大长度。
第二行输出k个正整数,依次表示选择的是输入文件中的第几个区间。
若有多组最优解,输出任意一组。

按左端点排序,i=1..n,取左端点前i小的区间中,右端点最大的k个,可以用堆维护。

#include<bits/stdc++.h>
typedef long long i64;
const int N=1e6+7;
char ib[N*30],*ip=ib;
int _(){int x;scanf("%d",&x);return x;}
struct itv{
    int l,r,id;
    bool operator<(const itv&w)const{return l<w.l;}
}is[N];
int n,k;
std::priority_queue<int,std::vector<int>,std::greater<int> >q1;
int ans=0,L=INT_MAX,R=INT_MIN;
void upd(int l,int r){
    if(r-l>ans)ans=r-l,R=r,L=l; 
}
int main(){
    n=_(),k=_();
    for(int i=0;i<n;++i){
        is[i].l=_();
        is[i].r=_();
        is[i].id=i+1;
    }
    std::sort(is,is+n);
    for(int i=0;i<k;++i)q1.push(is[i].r);
    upd(is[k-1].l,q1.top());
    for(int i=k;i<n;++i){
        int x=is[i].r;
        if(x>q1.top()){
            q1.push(x);
            q1.pop();
        }
        upd(is[i].l,q1.top());
    }
    printf("%d\n",ans);
    for(int i=0;k&&i<n;++i)
    if(is[i].l<=L&&is[i].r>=R){
        printf("%d ",is[i].id);
        --k;
    }
    return 0;
}

 

posted on 2017-11-28 01:41  nul  阅读(354)  评论(0编辑  收藏  举报