【單調棧優化】CodeForces-547B——D - Mike and Feet

前言

最後對答案的處理方法好妙... ...

思維——啊依舊是我的弱點

(話說題目中居然還有個小熊的圖片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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章