codeforce 754-D(求最大k个重叠区间)

来源:互联网 发布:网络语ojbk是什么意思 编辑:程序博客网 时间:2024/05/23 19:37

All our characters have hobbies. The same is true for Fedor. He enjoys shopping in the neighboring supermarket.

The goods in the supermarket have unique integer ids. Also, for every integer there is a product with id equal to this integer. Fedor hasn discount coupons, the i-th of them can be used with products with ids ranging from li tori, inclusive. Today Fedor wants to take exactlyk coupons with him.

Fedor wants to choose the k coupons in such a way that the number of such productsx that all coupons can be used with this productx is as large as possible (for better understanding, see examples). Fedor wants to save his time as well, so he asks you to choose coupons for him. Help Fedor!

Input

The first line contains two integers n andk (1 ≤ k ≤ n ≤ 3·105) — the number of coupons Fedor has, and the number of coupons he wants to choose.

Each of the next n lines contains two integersli andri ( - 109 ≤ li ≤ ri ≤ 109) — the description of the i-th coupon. The coupons can be equal.

Output

In the first line print single integer — the maximum number of products with which all the chosen coupons can be used. The products with which at least one coupon cannot be used shouldn't be counted.

In the second line print k distinct integersp1, p2, ..., pk (1 ≤ pi ≤ n) — the ids of the coupons which Fedor should choose.

If there are multiple answers, print any of them.

Example
Input
4 21 10040 70120 130125 180
Output
311 2 
Input
3 21 1215 2025 30
Output
01 2 
Input
5 21 105 1514 5030 7099 100
Output
213 4 
Note

In the first example if we take the first two coupons then all the products with ids in range[40, 70] can be bought with both coupons. There are31 products in total.

In the second example, no product can be bought with two coupons, that is why the answer is0. Fedor can choose any two coupons in this example.

  题目大意:某人有n张优惠券,每张优惠券都有一个优惠区间,比如说某张优惠券能优惠1~25号商品(1~25号为商品编号,一共25个商品),现在需要从n张优惠劵中选出k张,保证这k张能重叠优惠到最大商品区间来使这个区间中的商品经过多次优惠以至价格最低。本质就是从n个区间中选k个区间。

题解:这题我一开始用到暴力,复杂度为(n*(n-1))/2,没想到超时了,我的暴力思想是先对所给的区间左值排好序,从第k个商品开始,扫描前面商品,保留最小右值与第k个左值,保留所得区间,然后再从k+1个商品开始,扫描前面的商品,以此下去,不断改变最大区间,好像在第八组的时候超时了。参考别的博主用的是优先队列,受益匪浅。

使用优先队列,也是先对左值排序,选定k个商品,按右值从小到大进队,求重叠区间,然后出队(此时出队肯定是右值最小的,它出队对于后面区间的没有影响,因为后面区间左值大于它,重叠的区间不会比它大,自己考虑),不断更新最大值,这样只扫描了一遍就得出结果,在输出时也要注意,自己考虑技巧吧。下面是优先队列ac代码。

#include <iostream>#include <algorithm>#include <queue>using namespace std;typedef struct point{int start;int end;int id;}pt;pt p[300005];bool cmp (pt a,pt b){return a.start<b.start;}int main (){    int n,k;    int i,j,value,flag,l;    while (scanf ("%d%d",&n,&k)!=EOF)    {    priority_queue<int,vector<int>,greater<int> >q;\\队列申请在while里,放在外面要不断再把队列清空。    l=0;    value=0;    for (i=1;i<=n;i++)    {    cin>>p[i].start>>p[i].end;    p[i].id=i;        }        sort (p+1,p+n+1,cmp);        for (i=1;i<=n;i++)        {          l=p[i].start;          q.push(p[i].end);          while (q.size()>k)          q.pop();          if (q.size()==k)          {          if (q.top()-l+1>value)          {          value=q.top()-l+1;          flag=i;}  }}cout<<value<<endl;if (value==0){for (i=1;i<=k;i++){  if (i!=1)   cout<<" ";   cout<<i;    }    cout<<endl;}else{for (i=1;i<=flag;i++)\\要好好考虑,是个技巧。if (p[i].end-p[flag].start+1>=value)cout<<p[i].id<<" ";cout<<endl;}}return 0;}





原创粉丝点击