Description
有n只熊。他们站成一排队伍,从左到右依次1到n编号。第i只熊的高度是ai。
一组熊指的队伍中连续的一个子段。组的大小就是熊的数目。而组的力量就是这一组熊中最小的高度。
迈克想知道对于所有的组大小为x(1 ≤ x ≤ n)的,最大力量是多少。
题解
控制区间的idea。只要单调栈刷出每个点的控制区间,然后从后往前更新一下答案就可以了。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 200006
#define lowbit(x) (x&-x)
using namespace std;
inline char nc(){
static char buf[100000],*i=buf,*j=buf;
return i==j&&(j=(i=buf)+fread(buf,1,100000,stdin),i==j)?EOF:*i++;
}
inline int _read(){
char ch=nc();int sum=0;
while(!(ch>='0'&&ch<='9'))ch=nc();
while(ch>='0'&&ch<='9')sum=sum*10+ch-48,ch=nc();
return sum;
}
int n,top,L[maxn],R[maxn],ans[maxn],a[maxn],stack[maxn];
void push(int x){
while(top&&a[stack[top]]>=a[x])top--;
stack[++top]=x;
}
int main(){
freopen("mikestep.in","r",stdin);
freopen("mikestep.out","w",stdout);
n=_read();
for(int i=1;i<=n;i++)a[i]=_read();
for(int i=1;i<=n;i++){
push(i);
L[i]=stack[top-1]+1;
}
top=0;stack[0]=n+1;
for(int i=n;i>=1;i--){
push(i);
R[i]=stack[top-1]-1;
}
for(int i=1;i<=n;i++)ans[R[i]-L[i]+1]=max(a[i],ans[R[i]-L[i]+1]);
for(int i=n;i>=1;i--)ans[i]=max(ans[i],ans[i+1]);
for(int i=1;i<=n;i++)printf("%d ",ans[i]);
return 0;
}