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 }