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 }
View Code

猜你喜欢

转载自www.cnblogs.com/Dup4/p/10574141.html