还记得lyf说过k=2的方法,但是推广到k是其他的话有点麻烦。现在这里采取另外一种方法。
先将所有线段按照L进行排序,然后优先队列保存R的值,然后每次用最小的R值,和当前的L来维护答案即可。同时,如果Q的size()比k大,那么就弹出最小的R。
具体见代码:
1 #include <stdio.h> 2 #include <algorithm> 3 #include <string.h> 4 #include <set> 5 #include <vector> 6 #include <map> 7 #include <vector> 8 #include <queue> 9 using namespace std; 10 const int N = (int)3e5+5; 11 12 int n,k; 13 struct seg 14 { 15 int l, r, id; 16 bool operator < (const seg & A) const 17 { 18 return l < A.l; 19 } 20 }p[N]; 21 22 int main() 23 { 24 scanf("%d%d",&n,&k); 25 for(int i=1;i<=n;i++) {scanf("%d%d",&p[i].l,&p[i].r);p[i].id=i;} 26 sort(p+1,p+1+n); 27 priority_queue<int,vector<int>,greater<int> > Q; 28 int L = 0; 29 int ans = 0; 30 for(int i=1;i<=n;i++) 31 { 32 Q.push(p[i].r); 33 if(Q.size() > k) Q.pop(); 34 if(Q.size() == k && ans < Q.top() - p[i].l + 1) 35 { 36 ans = Q.top() - p[i].l + 1; 37 L = p[i].l; 38 } 39 } 40 if(ans == 0) 41 { 42 puts("0"); 43 int first = 0; 44 for(int i=1;i<=k;i++) 45 { 46 if(first) printf(" "); 47 else first = 1; 48 printf("%d",p[i].id); 49 } 50 puts(""); 51 } 52 else 53 { 54 printf("%d\n",ans); 55 int first = 0; 56 for(int i=1;i<=n && k>0;i++) 57 { 58 int l = p[i].l, r = p[i].r; 59 if(l<=L && L+ans-1<=r) 60 { 61 if(first) printf(" "); 62 else first = 1; 63 printf("%d",p[i].id); 64 k--; 65 } 66 } 67 puts(""); 68 } 69 return 0; 70 }
另外,输出方案的方式也值得注意一下。
时间: 2024-10-12 18:14:42