前言
最後對答案的處理方法好妙... ...
思維——啊依舊是我的弱點
(話說題目中居然還有個小熊的圖片qwq!可耐)
題目
Mike is the president of country What-The-Fatherland. There are n bears living in this country besides Mike. All of them are standing in a line and they are numbered from 1 to n from left to right. i-th bear is exactly ai feet high.
A group of bears is a non-empty contiguous segment of the line. The size of a group is the number of bears in that group. The strength of a group is the minimum height of the bear in that group.
Mike is a curious to know for each x such that 1 ≤ x ≤ n the maximum strength among all groups of size x.
Input
The first line of input contains integer n (1 ≤ n ≤ 2 × 105), the number of bears.
The second line contains n integers separated by space, a1, a2, ..., an (1 ≤ ai ≤ 109), heights of bears.
Output
Print n integers in one line. For each x from 1 to n, print the maximum strength among all groups of size x.
Examples
Input
10
1 2 3 4 5 4 3 2 1 6
Output
6 4 4 3 3 2 2 1 1 1
題目大意
對於所有連續的長度爲x的區間(1<=x<=n),x從1到n輸出:長度爲x的所有區間最小值中的最大值
分析
方法和上一題差不多(Largest Rctangle in a Histogram)
對於每個數a[ i ],求出以a[ i ]爲最小值的區間左右端點L[ i ]和R[ i ],方法是做兩遍單調棧(詳情見上方鏈接)
對於長度爲len的區間(1<=len<=n)ans[ len ]=max( ans[ len ] , a[ i ] )
因爲我們求出的L[ i ]和R[ i ]是以a[ i ]爲最小值的,所以所有長度爲len的區間直接取max就可以了
接下來有個問題:有可能不存在某些長度爲len的區間,怎麼辦呢?
可以這樣想:對於有len個數的區間(即長度爲len),它的最大值ans[ len ]一定至少爲ans[ len+1 ]
意會一下吧,想了半天不知道怎麼解釋qwq...找了個不錯的解釋:
最後還要從len=n-1~1遍歷,令ans[len]=max(ans[len],a[len+1])。
爲什麼要這麼做?
因爲不這樣做,如1 2 3 2 1這組樣例,只能求出ans[1]、ans[3]、ans[5],像ans[2]、ans[4]都是空的。
這樣做的意義就是如果ans[len]爲空,則把ans[len+1]的值給它。
爲什麼是ans[len+1]的值,首先ans[len]>=ans[len+1],假設我們有一個長度爲len+1的只有x~y的區間,min=2,則a[len+1]=2,
假設a[len]會大於a[len+1],那麼必定存在x+1~y或者x~y-1的區間且min>2,但是如果ans[len-1]爲空則說明沒有這樣的區間
所以取ans[len]=ans[len+1]。
代碼
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int MAXN=2e5;
ll a[MAXN+5],st[MAXN+5],L[MAXN+5],R[MAXN+5],ans[MAXN+5];
int n;
void Solve()
{
int top=0;
//計算L
for(int i=1;i<=n;i++)
{
while(top>0&&a[st[top-1]]>=a[i])
top--;
L[i]=top==0?1:(st[top-1]+1);
st[top++]=i;
}
//計算R
top=0;
for(int i=n;i>=1;i--)
{
while(top>0&&a[st[top-1]]>=a[i])
top--;
R[i]=top==0?n:(st[top-1]-1);
st[top++]=i;
}
for(int i=1;i<=n;i++)
{
int len=R[i]-L[i]+1;
ans[len]=max(ans[len],a[i]);
}
//for(int i=1;i<=n;i++)
// printf("%d:L:%d R:%d ans:%d\n",i,L[i],R[i],ans[i]);
for(int i=n-1;i>=1;i--)
ans[i]=max(ans[i],ans[i+1]);
for(int i=1;i<=n;i++)
printf("%lld ",ans[i]);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
Solve();
return 0;
}