C. Present(二分 + 扫描线)

题目链接:http://codeforces.com/contest/460/problem/C

题意: n盆花,浇k次水, 每次可使花高度 + 1, 每次可浇相邻的w盆,ai 表示 i-th盆花 的高度 问:当浇完m次后,最矮的一盆花最高可以使多少?

解题思路: 二分 + 扫描线, 由于高度最高10e9 + 10e5 ,最小1, 然后在 这范围内二分搜索。 

          这道题主要的还是check,  怎样检查 浇完后是否能达到高度 h。 用树状数组或线段树 自然可以, 复杂度: 建树(nlogn ) + 点查询(nlogn)。 不过还有种更小巧精悍的方法: 扫描线(n)。 

         例如在【0,2),【1,3)范围内分别 + 1, 可以先f[0] += 1, f[2] -= 1, f[1] += 1, f[3] -= 1,f: 1,1,-1,-1, 计算结果是,从左完后加: 1, 1 +1,1+1-1,1+1-1-1. 

 1 /***Good Luck***/
 2 // 二分 + 扫描线
 3 #define _CRT_SECURE_NO_WARNINGS
 4 #include <iostream>
 5 #include <cstdio>
 6 #include <cstdlib>
 7 #include <cstring>
 8 #include <string>
 9 #include <algorithm>
10 #include <stack>
11 #include <map>
12 #include <queue>
13 #include <vector>
14 #include <set>
15 #include <functional>
16 #include <cmath>
17 
18 #define Zero(a) memset(a, 0, sizeof(a))
19 #define Neg(a)  memset(a, -1, sizeof(a))
20 #define All(a) a.begin(), a.end()
21 #define PB push_back
22 #define inf 0x3f3f3f3f
23 #define inf2 0x7fffffffffffffff
24 #define ll long long
25 using namespace std;
26 //#pragma comment(linker, "/STACK:102400000,102400000")
27 const int maxn = 100005;
28 int arr[maxn];
29 int f[maxn + maxn]; 
30 int n, m, w;
31 
32 bool check(int mnh) {
33     Zero(f);
34     int tmpm = m;
35     for (int i = 1; i <= n; ++i) {// 扫描线
36         f[i] = f[i] + f[i - 1];
37         int d = max(0, mnh - arr[i] - f[i]);
38         tmpm -= d;
39         f[i] += d;
40         f[i + w] -= d;
41         if (tmpm < 0) return false;
42     }
43     return true;
44 }
45 
46 void solve() {
47     int l = 0, r = 1000000000 + maxn;
48     int mid;
49     while (l < r) {
50         mid = (l + r + 1) >> 1;
51         if (check(mid)) {
52             l = mid ;
53         } else {
54             r = mid - 1;
55         }
56     }
57     cout << r  << endl;
58 }
59 int main() {
60     //freopen("data.out", "w", stdout);
61     //freopen("data.in", "r", stdin);
62     cin.sync_with_stdio(false);
63     cin >> n >> m >> w;
64     for (int i = 1; i <= n; ++i)
65         cin >> arr[i];
66     solve();
67     return 0;
68 }

 

posted @ 2014-08-21 20:06  yeahpeng  阅读(246)  评论(0编辑  收藏  举报