2528. 最大化城市的最小电量
2528. 最大化城市的最小电量
题目链接:2528. 最大化城市的最小电量
代码如下:
//参考链接:https://leetcode.cn/problems/find-x-sum-of-all-k-long-subarrays-ii/solutions/2948867/liang-ge-you-xu-ji-he-wei-hu-qian-x-da-p-2rcz
class Solution {
public:long long maxPower(vector<int>& stations, int r, int k) {int n = stations.size();//前缀和vector<long long> sum(n + 1);for (int i = 0;i < n;i++) {sum[i + 1] = sum[i] + stations[i];}//初始电量vector<long long> power(n);long long mn = LLONG_MAX;for (int i = 0;i < n;i++) {power[i] = sum[min(i + r + 1, n)] - sum[max(i - r, 0)];mn = min(mn, power[i]);}auto check = [&](long long low)->bool {vector<long long> diff(n + 1);long long sum_d = 0, built = 0;for (int i = 0;i < n;i++) {sum_d += diff[i];//累加差分值long long m = low - (power[i] + sum_d);//当前位置还需要建造的电站数if (m <= 0) {continue;}//需要在i+r额外建造m个供电站built += m;if (built > k) {//不满足要求return false;}//把区间[i, i+2r]的电量都增加1sum_d += m;//由于diff[i]后面不会再被访问,我们直接加到sum_d上diff[min(i + r * 2 + 1, n)] -= m;}return true;};//开区间二分long long left = mn + k / n, right = mn + k + 1;while (left + 1 < right) {long long mid = left + (right - left) / 2;(check(mid) ? left : right) = mid;}return left;}
};
