/*
Problem: Minimum Maximum Request Transfer Latency
Company Tag: Media.net OA
Problem Statement:
We are given two arrays:
requests[i] = number of requests currently present on server i
max_req[i] = maximum number of requests server i can finally handle
We can move requests from one server to another.
Moving one request from server i to server j has latency:
abs(i - j)
After redistribution:
final_requests[i] <= max_req[i]
Our task is to minimize the maximum latency among all moved requests.
If total requests are greater than total capacity, return -1.
Constraints:
1 <= n <= 100000
0 <= requests[i] <= 1000000000
0 <= max_req[i] <= 1000000000
Brute Force:
Try all possible ways of moving requests.
Why Brute Force Fails:
requests[i] can be very large.
We cannot simulate every single request movement.
Optimized Idea:
I binary search the answer.
For a fixed distance d:
Extra requests from server i can only move to servers in range:
[i - d, i + d]
Then I greedily place extra requests into available free capacity.
Explanation Block:
First, I check if total requests <= total capacity.
Then I store all servers which have free capacity.
For a fixed d:
I process surplus servers from left to right.
For each surplus server, I move its extra requests to the nearest
possible free-capacity server within distance d.
If all extra requests are placed, d is valid.
Then I try smaller d using binary search.
Dry Run:
requests = [1, 3, 2, 4]
max_req = [2, 1, 5, 3]
Server 1 has 2 extra requests.
Server 3 has 1 extra request.
Server 2 has free capacity 3.
With d = 1:
Move 2 requests from server 1 to server 2.
Move 1 request from server 3 to server 2.
Answer = 1
Time Complexity:
O(n log n)
Space Complexity:
O(n)
*/
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int minimumMaximumLatency(vector<ll>& requests, vector<ll>& max_req) {
int n = requests.size();
ll totalRequests = 0;
ll totalCapacity = 0;
// First I check whether redistribution is possible.
for (int i = 0; i < n; i++) {
totalRequests += requests[i];
totalCapacity += max_req[i];
}
if (totalRequests > totalCapacity) {
return -1;
}
vector<int> freePos;
vector<ll> freeCap;
// Store only servers that have free capacity.
for (int i = 0; i < n; i++) {
if (max_req[i] > requests[i]) {
freePos.push_back(i);
freeCap.push_back(max_req[i] - requests[i]);
}
}
auto possible = [&](int d) -> bool {
vector<ll> remaining = freeCap;
// ptr points to current free-capacity server.
int ptr = 0;
for (int i = 0; i < n; i++) {
// Extra requests that must be moved out from server i.
ll extra = max(0LL, requests[i] - max_req[i]);
while (extra > 0) {
// If a free server is too far left,
// current and future surplus servers cannot use it.
while (ptr < (int)freePos.size() && freePos[ptr] < i - d) {
ptr++;
}
// If no free server exists, or nearest free server is too far right,
// then distance d is not enough.
if (ptr == (int)freePos.size() || freePos[ptr] > i + d) {
return false;
}
// Move as many requests as possible to this server.
ll take = min(extra, remaining[ptr]);
extra -= take;
remaining[ptr] -= take;
// If this free server becomes full, move to the next one.
if (remaining[ptr] == 0) {
ptr++;
}
}
}
return true;
};
int low = 0;
int high = n - 1;
int ans = n - 1;
// Binary search the minimum possible maximum latency.
while (low <= high) {
int mid = low + (high - low) / 2;
if (possible(mid)) {
ans = mid;
high = mid - 1;
} else {
low = mid + 1;
}
}
return ans;
}
int main() {
vector<ll> requests = {1, 3, 2, 4};
vector<ll> max_req = {2, 1, 5, 3};
cout << minimumMaximumLatency(requests, max_req) << endl;
return 0;
}