Problem Link🔗:Problem - B - Codeforces
Problem Description:
Approach: Monotonic Stack & Suffix Maximum
We need to answer, for every length k from 1 to n, the maximum possible minimum value among all contiguous subarrays of length k.
Instead of checking every subarray for every k, we reverse the perspective: for each element a[i], determine the largest interval in which a[i] can serve as the minimum. If that interval has length len[i], then a[i] is a valid candidate for every length k <= len[i].
We find the boundaries of each element's "dominance interval" using a monotonic stack:
L[i]: the nearest position to the left ofiwith a value strictly smaller thana[i].R[i]: the nearest position to the right ofiwith a value strictly smaller thana[i].
Then the maximum interval length where a[i] is the minimum is:
len[i] = R[i] - L[i] - 1
After computing len[i] for all elements, we build an array best where best[L] stores the maximum a[i] among all elements whose dominance length is exactly L:
best[len[i]] = max(best[len[i]], a[i])
Finally, for each length k, the answer is the maximum value among all best[L] with L >= k. This can be computed with a suffix maximum recurrence:
ans[n] = best[n]
ans[k] = max(best[k], ans[k + 1]) for k = n-1 down to 1
Time Complexity Analysis
- Computing
L[i]with a monotonic stack takesO(n)time. - Computing
R[i]with a monotonic stack takesO(n)time. - Building the
bestarray takesO(n)time. - The suffix maximum recurrence takes
O(n)time. - Outputting the answers takes
O(n)time.
Therefore, the overall time complexity is:
O(n)
Since n <= 2 * 10^5, this is easily fast enough.
Space Complexity
We store several arrays of size n + 1: the input array, L, R, len, best, and ans. The monotonic stack also uses at most O(n) space.
O(n)
Implementation:
#include<iostream>
#include<vector>
#include<stack>
int main(){
int n;
std::cin >> n;
std::vector<int> v(n+1);
std::vector<int> L(n+1), R(n+1);
std::stack<int> s;
std::vector<int> len(n+1);
std::vector<int> best(n+1, 0);
std::vector<int> res(n+1, 0);
for(int i=1; i<=n; i++) std::cin >> v[i];
for(int i=1; i<=n; i++){
while(s.size()>0&&v[s.top()]>=v[i]) s.pop();
s.size() == 0 ? L[i] = 0 : L[i] = s.top();
s.push(i);
}
while(!s.empty()) s.pop();
for(int i=n; i>=1; i--){
while(s.size()>0&&v[s.top()]>=v[i]) s.pop();
s.size() == 0 ? R[i] = n+1 : R[i] = s.top();
s.push(i);
}
for(int i=1; i<=n; i++) len[i] = R[i] - L[i] - 1;
for(int i=1; i<=n; i++) best[len[i]] = std::max(best[len[i]], v[i]);
res[n] = best[n];
for(int i=n-1; i>=1; i--) res[i] = std::max(best[i], res[i+1]);
for(int i=1; i<=n; i++) std::cout << res[i] << " ";
return 0;
}