您的位置:首页 > 其它

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

2017-08-14 23:16 399 查看
思路:

考虑到补签卡一定是连续放置才更优,所以直接根据起始位置枚举。预先处理区间之间的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\n", maxn);
45     }
46     return 0;
47 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: