对与输入的每个数num[i]用单调栈可以找到最大的l[i](l[i] < i, num[l[i]] < num[i])和最小的r[i](r[i] > i, num[r[i]] < num[i]),
那么num[i]为最小值的区间的最大长度为r[i] - l[i] - 1;
用ans[k]表示长度为K的区间的最小值的最大值.
因为如果有一个长度为6的窗口,里面的最小值的最大值是10,那么长度为5的窗口的最小值的最大值肯定不会小于10.
所以我们在计算完各个长度的答案后还要从后往前更新一遍值。
#include <bits/stdc++.h>
#define INF 1e9
#define maxn 200005
using namespace std;
typedef long long ll;
int num[200005], l[maxn], r[maxn], ans[maxn];
stack<int> s;
int main(){
// freopen("in.txt", "r", stdin);
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i++)
scanf("%d", num+i);
for(int i = 1; i <= n; i++){
while(!s.empty() && num[s.top()] >= num[i])
s.pop();
if(s.empty())
l[i] = 0;
else
l[i] = s.top();
s.push(i);
}
while(!s.empty())
s.pop();
for(int i = n; i >= 1; i--){
while(!s.empty() && num[s.top()] >= num[i])
s.pop();
if(s.empty())
r[i] = n + 1;
else
r[i] = s.top();
s.push(i);
}
for(int i = 1; i <= n; i++){
int len = r[i] - l[i] - 1;
ans[len] = max(ans[len], num[i]);
}
for(int i = n-1; i >= 1; i--){
ans[i] = max(ans[i], ans[i+1]);
}
printf("%d", ans[1]);
for(int i = 2; i <= n; i++)
printf(" %d", ans[i]);
puts("");
return 0;
}