百度之星2017初赛B1006 小小粉丝度度熊

思路:

考虑到补签卡一定是连续放置才更优,所以直接根据起始位置枚举。预先处理区间之间的gap的前缀和,在枚举过程中二分即可。复杂度O(nlog(n))。

实现:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <vector>
 4 #include <algorithm>
 5 using namespace std;
 6 typedef long long ll;
 7 
 8 const ll INF = 0x3f3f3f3f;
 9 
10 int main()
11 {
12     int n, m;
13     while (scanf("%d %d", &n, &m) != EOF)
14     {
15         vector<pair<int, int>> v;
16         int x, y;
17         for (int i = 0; i < n; i++)
18         {
19             scanf("%d %d", &x, &y);
20             v.push_back(pair<int, int>(x, y));
21         }
22         sort(v.begin(), v.end());
23         vector<pair<int, int>> res;
24         res.push_back(v[0]);
25         for (int i = 1; i < v.size(); i++)
26         {
27             if (v[i].first > res.back().second + 1) res.push_back(v[i]);
28             else res.back().second = max(res.back().second, v[i].second);
29         }
30         vector<ll> sum(res.size() - 1);
31         for (int i = 0; i < res.size() - 1; i++)
32             sum[i] = (ll)res[i + 1].first - 1 - res[i].second;
33         sum.push_back(INF);
34         for (int i = 1; i < sum.size(); i++)
35             sum[i] += sum[i - 1];
36         ll maxn = 0;
37         for (int i = 0; i < sum.size(); i++)
38         {
39             ll tmp = (i == 0 ? 0 : sum[i - 1]);
40             int pos = upper_bound(sum.begin() + i, sum.end(), m + tmp) - sum.begin();
41             ll tmp2 = (pos == i ? m : m - (sum[pos - 1] - tmp));
42             maxn = max(maxn, res[pos].second - res[i].first + 1 + tmp2);
43         }
44         printf("%lld
", maxn);
45     }
46     return 0;
47 }
原文地址:https://www.cnblogs.com/wangyiming/p/7360976.html