题意:
n个数,现将这n个数中取出每连续的k个(k 从1~n)组成一组,组内的值为这一组的最小值,现在要求所有大小为k的组的最大值。
思路:
单调栈。维护一个单调递增栈(从栈底到栈顶单调递增),存每个点贡献的长度和他的值。
比如1 2 3 4 5 4 3 2 1 6
第一个1,栈为空,那么把它加入栈中,贡献的长度为1,值为1。
依次直到第6个数 4,由于栈顶元素比4大,那么弹出栈顶元素,并且计算现在的长度(统计现在长度),即弹出的这些
数字能够贡献的长度,知道栈顶元素比当前的值小,然后将当前的4入栈,它能贡献的长度就是统计的长度。
依次类推,要注意最后栈不一定是空的,所以剩下的元素也要处理。
#include<bits/stdc++.h>
using namespace std;
#define N 200010
int n, a[N], ans[N];
struct node
{
int val, len;
node(){}
node(int len, int val):len(len), val(val){}
};
stack<node> stk;
int main()
{
while(cin>>n)
{
while(!stk.empty()) stk.pop();
for(int i=1; i<=n; i++) cin>>a[i];
for(int i=1;i<=n; i++)
{
int len=0;
while(!stk.empty())
{
node tp=stk.top();
if(tp.val<a[i]) break;
stk.pop();
len+=tp.len;
ans[len]=max(ans[len], tp.val);
}
stk.push(node(len+1,a[i]));
}
int len=0;
while(!stk.empty())
{
node tp=stk.top();
stk.pop();
len+=tp.len;
ans[len]=max(ans[len], tp.val);
}
for(int i = n; i >= 1; i--) ans[i]=max(ans[i],ans[i+1]);
for(int i=1; i<=n; i++) printf("%d%c", ans[i], i==n?'\n':' ');
}
return 0;
}