[BZOJ5102]Prawnicy

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个正整数,依次表示选择的是输入文件中的第几个区间。
若有多组最优解,输出任意一组。

Sample Input

6 3
3 8
4 12
2 6
1 10
5 9
11 12

Sample Output

4
1 2 4

HINT

Source

做这道题的时候状态还不错,很快就想出来了

其实也是一个比较套路的贪心,假如我们把所有的$L$从小到大排序,那么限制区间大小的就是最大的$L$

这时我们把最大的$L$和最小的$R$计算一下答案,最小值可以用堆来维护

如果当前堆中元素的个数超过$k$,我们就选择$R$最小的弹出

代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<queue>
 4 #include<algorithm>
 5 #define M 1000100
 6 using namespace std;
 7 int n,k,tot,ans;
 8 int st[M];
 9 struct point{int l,r,id;}a[M];
10 struct Node{int id,v;};
11 priority_queue<Node>q;
12 bool cmp(point a1,point a2) {return a1.l<a2.l;}
13 bool operator < (Node a1,Node a2) {return a1.v>a2.v;} 
14 int main()
15 {
16     scanf("%d%d",&n,&k);
17     for(int i=1;i<=n;i++) 
18         scanf("%d%d",&a[i].l,&a[i].r),a[i].id=i;
19     sort(a+1,a+1+n,cmp);
20     for(int i=1;i<=n;i++)
21     {
22         q.push((Node){a[i].id,a[i].r});
23         while(q.top().v<a[i].l) q.pop();
24         if(q.size()>k) q.pop();
25         if(q.size()==k) ans=max(ans,q.top().v-a[i].l);
26     }
27     while(!q.empty()) q.pop();
28     for(int i=1;i<=n;i++)
29     {
30         q.push((Node){a[i].id,a[i].r});
31         while(q.top().v<a[i].l) q.pop();
32         if(q.size()>k) q.pop();
33         if(q.size()==k&&ans==q.top().v-a[i].l)
34         {
35             while(!q.empty())
36                 st[++tot]=q.top().id,q.pop();
37         }
38     }
39     sort(st+1,st+1+k);
40     printf("%d\n",ans);
41     for(int i=1;i<=k;i++) printf("%d ",st[i]);
42     return 0;
43 }

 

posted @ 2018-11-23 21:53  Slr  阅读(134)  评论(0编辑  收藏  举报