POI2012STU-Well
POI #Year2012 #二分
考虑二分答案,然后如果 ,那么一定要提前操作掉,先把这种情况搞掉
然后考虑枚举一个位置变成 ,在上面的操作后,可以保证 ,那么这时还需要操
作的区间 , 都随着 的增加而增加,维护这两个端点直接算答案
// Author: xiaruize const int N = 1e6 + 10; int n, m; int a[N]; int s[N], sum[N]; int check(int x) { memcpy(s, a, sizeof(s)); int cnt = 0; rep(i, 2, n) s[i] = min(s[i - 1] + x, s[i]); per(i, n - 1, 1) s[i] = min(s[i], s[i + 1] + x); rep(i, 1, n) { cnt += a[i] - s[i]; sum[i] = sum[i - 1] + s[i]; } for (int i = 1, l = 1, r = 1; i <= n; i++) { while (r < n && (r - i + 1) * x < s[r + 1]) r++; while (l < i && (i - l) * x >= s[l]) l++; if (cnt + sum[r] - sum[l - 1] - x * ((i - l) * (i - l + 1) / 2 + (r - i) * (r - i + 1) / 2) <= m) return i; } return -1; } void solve() { cin >> n >> m; rep(i, 1, n) cin >> a[i]; int l = 0, r = 1e9; pii res = {-1, -1}; while (l < r) { int mid = l + r >> 1; int v = check(mid); if (v == -1) l = mid + 1; else { r = mid; res = {mid, v}; } } cout << res.second << ' ' << res.first << endl; } #ifndef ONLINE_JUDGE bool end_of_memory_use; #endif signed main() { // freopen(".in","r",stdin); // freopen(".out","w",stdout); ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int testcase = 1; // cin >> testcase; while (testcase--) solve(); #ifndef ONLINE_JUDGE cerr << "Memory use:" << (&end_of_memory_use - &start_of_memory_use) / 1024.0 / 1024.0 << "MiB" << endl; cerr << "Time use:" << (double)clock() / CLOCKS_PER_SEC * 1000.0 << "ms" << endl; #endif return 0; }
本文作者:xiaruize's Blog
本文链接:https://www.cnblogs.com/xiaruize/p/18156739
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步