BZOJ 5102: [POI2018]Prawnicy
考虑最优解的集合中一定有一个$l$最大的,我们就去枚举左端点,把所有$l$小于等于它的全丢进堆里,取前$k$个即可。
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define N 1000010 5 #define fi first 6 #define se second 7 #define pii pair <int, int> 8 int n, k; 9 struct node 10 { 11 int l, r, id; 12 void scan(int _id) 13 { 14 id = _id; 15 scanf("%d%d", &l, &r); 16 } 17 bool operator < (const node &other) const 18 { 19 return l < other.l; 20 } 21 }a[N]; 22 23 void work() 24 { 25 priority_queue <pii, vector <pii>, greater <pii> > pq; 26 int Max = 0, L = -1, R = -1; 27 for (int i = 1; i <= n; ++i) 28 { 29 pq.push(pii(a[i].r, a[i].id)); 30 if ((int)pq.size() > k) 31 pq.pop(); 32 if ((int)pq.size() == k) 33 { 34 int t = max(0, pq.top().first - a[i].l); 35 if (t > Max) 36 { 37 Max = t; 38 L = a[i].l; 39 R = pq.top().fi; 40 } 41 } 42 } 43 printf("%d\n", Max); 44 for (int i = 1; i <= n; ++i) 45 { 46 if (a[i].l <= L && a[i].r >= R) 47 { 48 printf("%d", a[i].id); 49 if (k == 1) 50 { 51 puts(""); 52 return; 53 } 54 else 55 { 56 --k; 57 putchar(' '); 58 } 59 } 60 } 61 } 62 63 void Run() 64 { 65 while (scanf("%d%d", &n, &k) != EOF) 66 { 67 for (int i = 1; i <= n; ++i) 68 a[i].scan(i); 69 sort(a + 1, a + 1 + n); 70 work(); 71 } 72 } 73 74 int main() 75 { 76 #ifdef LOCAL 77 freopen("Test.in", "r", stdin); 78 #endif 79 80 Run(); 81 return 0; 82 }