1. 程式人生 > >Newcoder 58 B.棧和排序(水~)

Newcoder 58 B.棧和排序(水~)

Description

給你一個1n1\rightarrow n的排列和一個棧,入棧順序給定

你要在不打亂入棧順序的情況下,對陣列進行從大到小排序

當無法完全排序時,請輸出字典序最大的出棧序列

Input

第一行一個數nn

第二行nn個數,表示入棧的順序,用空格隔開,結尾無空格

(1n106)(1\le n\le 10^6)

Output

輸出一行nn個數表示答案,用空格隔開,結尾無空格

Sample Input

5 2 1 5 3 4

Sample Output

5 4 3 1 2

Solution

對於當前入棧元素aia_i,如果aiaj,j>

ia_i\ge a_j,\forall j>i,那麼aia_i是之後的最大值,故需要出棧,否則後面會有更大的元素可以增加答案的字典序,不能出棧,只需要實現維護一下字尾最大值即可,時間複雜度O(n)O(n)

Code

#include<cstdio>
using namespace std;
const int maxn=1000005;
int n,a[maxn],mx[maxn],ans[maxn],vis[maxn];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&a[i]);
	mx[n]=n;
	for(int i=n-1;i>=1;i--)
		if(a[i]<a[mx[i+1]])mx[i]=mx[i+1];
		else mx[i]=i;
	int res=0;
	for(int i=1;i<=n;i++)
		if(a[i]==a[mx[i]])ans[++res]=a[i],vis[i]=1;
	for(int i=n;i>=1;i--)
		if(!vis[i])ans[++res]=a[i];
	for(int i=1;i<=n;i++)printf("%d%c",ans[i],i==n?'\n':' ');
	return 0;
}