码迷,mamicode.com
首页 > 其他好文 > 详细

Codeforces-754D Fedor and coupons

时间:2017-09-22 23:55:11      阅读:181      评论:0      收藏:0      [点我收藏+]

标签:logs   传送门   printf   blog   最小   pop   sort   scanf   can   

传送门

 

给你n(<=3e5)个区间,让你从中选出k(<=n)个,使这些区间的交集长度最大。区间范围[-1e9, 1e9]

要求输出区间长度和选取的区间编号

 

典型的优先队列问题。先把区间按左值从小到大排序,这样做保证了后面取出来的区间的左值大于先前所有的,然后我门就只需要比较右值了。注意到最终答案的区间是由k个区间交,所以我们要维护k个区间的信息。每次由这k个右值里的最小值来减去k个左值里的最大值再加一去更新答案。由于最后取出的区间的左值最大(排序过),所以我们维护k个右值即可。选取优先队列维护

 

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 #define INF 0x3f3f3f3f
 6 using namespace std;
 7 typedef long long LL;
 8 int N, K;
 9 const int maxn = 3e5 + 10;
10 struct node {
11     int left, right, num;
12 } seg[maxn];
13 int left, right;
14 
15 bool cmp(const node &A, const node &B) {
16     return A.left < B.left;
17 }
18 
19 int main() {
20     scanf("%d%d", &N, &K);
21     for (int i = 0; i < N; i++) {
22         scanf("%d%d", &seg[i].left, &seg[i].right);
23         seg[i].num = i + 1;
24     }
25      int tmp = 1e9 + 10;;
26      sort(seg, seg + N, cmp);
27     priority_queue<int, vector<int>, greater<int> > que;
28      for (int i = 0; i < K; i++) {
29          que.push(seg[i].right);
30          tmp = min(tmp, seg[i].right);
31      }    
32      int ans = 0;
33      if (!(tmp < seg[K - 1].left)) {
34          ans = tmp - seg[K - 1].left + 1;
35          left = seg[K - 1].left;
36          right = tmp;
37      }
38      tmp = que.top();
39      for (int i = K; i < N; i++) {
40          if (seg[i].right > tmp) {
41              que.pop();
42              que.push(seg[i].right);
43              tmp = que.top();
44              if (tmp - seg[i].left + 1 > ans) {
45                  ans = tmp - seg[i].left + 1;
46                  right = tmp;
47                  left = seg[i].left;
48              }
49          }
50      }
51      printf("%d\n", ans);
52      if (ans == 0) {
53          for (int i = 1; i <= K; i++) {
54              printf("%d%c", i, i == K ? \n :  );
55          }
56      } else {
57          for (int i = 0; i < N && K; i++) {
58              if (seg[i].left <= left && right <= seg[i].right) {
59                  printf("%d%c", seg[i].num, K == 1 ? \n :  );
60                  --K;
61              }
62          }
63       }
64     return 0;
65 }

 

Codeforces-754D Fedor and coupons

标签:logs   传送门   printf   blog   最小   pop   sort   scanf   can   

原文地址:http://www.cnblogs.com/xFANx/p/7577280.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!