标签:答案 i++ std present ble size 判断 思路 false
题目链接:https://www.luogu.org/problem/CF460C
思路:
考虑二分答案。
对于这$n$个数,我们可以从左往右,若发现小于当前答案的数,把$[i,i+w]$之间的所有数都加到当前答案的数值,判断总次数与$m$的关系就行了。
对于更新和查询的操作,不妨使用树状数组维护差分数组。
代码:
#include <bits/stdc++.h> const int MAXN = 100050; const int INF = 1e9 + 5; using namespace std; int n, m, w, Min = INF, l, r, ans, a[MAXN], b[MAXN]; struct Tree_Array { int lowbit(int x) { return x & (-x); } void add(int pos, int val) { for(int i = pos; i <= n; i += lowbit(i)) b[i] += val; } int ask(int pos) { int sum = 0; for(int i = pos; i >= 1; i -= lowbit(i)) sum += b[i]; return sum; } }Tree; bool check(int x) { int cnt = 0, last = 0; memset(b, 0, sizeof(b)); for(int i = 1; i <= n; i++) { Tree.add(i, a[i] - x - last); last = a[i] - x; } for(int i = 1; i <= n; i++) { int res = Tree.ask(i); if(res < 0) { cnt += -res; if(cnt > m) return false; Tree.add(i, -res); Tree.add(i + w, res); } } return true; } int main() { cin >> n >> m >> w; for(int i = 1; i <= n; i++) { cin >> a[i]; Min = min(Min, a[i]); } l = Min, r = Min + m; while(l <= r) { int mid = (l + r) >> 1; if(check(mid)) { ans = mid; l = mid + 1; } else r = mid - 1; } cout << ans << endl; return 0; }
标签:答案 i++ std present ble size 判断 思路 false
原文地址:https://www.cnblogs.com/BeyondLimits/p/11367947.html