C2. Skyscrapers (hard version)

C2. Skyscrapers (hard version)

time limit per test:3 seconds
memory limit per test:512 megabytes
inputstandard input
outputstandard output

This is a harder version of the problem. In this version n≤500000

The outskirts of the capital are being actively built up in Berland. The company “Kernel Panic” manages the construction of a residential complex of skyscrapers in New Berlskva. All skyscrapers are built along the highway. It is known that the company has already bought n plots along the highway and is preparing to build n skyscrapers, one skyscraper per plot.

Architects must consider several requirements when planning a skyscraper. Firstly, since the land on each plot has different properties, each skyscraper has a limit on the largest number of floors it can have. Secondly, according to the design code of the city, it is unacceptable for a skyscraper to simultaneously have higher skyscrapers both to the left and to the right of it.

Formally, let’s number the plots from 1 to n. Then if the skyscraper on the i-th plot has ai floors, it must hold that ai is at most mi (1≤ai≤mi). Also there mustn’t be integers j and k such that j<iai<ak. Plots j and k are not required to be adjacent to i.

The company wants the total number of floors in the built skyscrapers to be as large as possible. Help it to choose the number of floors for each skyscraper in an optimal way, i.e. in such a way that all requirements are fulfilled, and among all such construction plans choose any plan with the maximum possible total number of floors.

Input
The first line contains a single integer n (1≤n≤500000) — the number of plots.

The second line contains the integers m1,m2,…,mn (1≤mi≤109) — the limit on the number of floors for every possible number of floors for a skyscraper on each plot.

Output
Print n integers ai — the number of floors in the plan for each skyscraper, such that all requirements are met, and the total number of floors in all skyscrapers is the maximum possible.

If there are multiple answers possible, print any of them.

Examples
input

5
1 2 3 2 1

output

1 2 3 2 1 

input

3
10 6 8

output

10 6 6 

Note
In the first example, you can build all skyscrapers with the highest possible height.
In the second test example, you cannot give the maximum height to all skyscrapers as this violates the design code restriction. The answer [10,6,6] is optimal. Note that the answer of [6,6,8] also satisfies all restrictions, but is not optimal.

題目大意

給你一個數字 n ,一共有 n 個數,你可以調整這串數字的大小,最後滿足任何一個數字兩邊的數字都不大於它,調整的時候只能將一個數字調整的比他小;

解題思路

我們可以想象到這個答案只有三種形態,
1:單調非遞增的 如:1 2 3 3 4 5 6
2:單調非遞減的 如:6 5 4 3 3 2 1
3:中間某處凸起的,如:1 2 3 6 5 4 3
這樣的話我們其實可以通過用單調棧從左開始按非遞增的規則進行求一個前綴和;然後再從右開始用單調棧求一個後綴和,然後,再跑一遍看看以哪一個位置爲最高點的結果最大;然後我們就可以按照這個點爲最高點像兩遍更新了;

代碼

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int a[500100],l[500100],r[500100];//l r 分別記錄位置 
ll suml[500100],sumr[500100];//用於求前綴和 

int main ()
{
	ios::sync_with_stdio(0);
	int n; 
	cin>>n;
	for(int i=1,j=0;i<=n;i++)//從左到右選 
	{
		cin>>a[i];
		j=i-1;
		while(j>0&&a[i]<a[j]) j=l[j];//單調棧進行篩選,如果滿足單調性就放進去 
		l[i]=j;
		suml[i]=suml[j]+1LL*(i-j)*a[i];
	}
	ll s=0;int t;// t 用來記錄最高點 
	for(int i=n,j=n+1;i>0;i--)//從右到左選 
	{
		j=i+1;
		while(j<=n&&a[i]<a[j]) j=r[j];
		r[i]=j;
		sumr[i]=sumr[j]+1LL*(j-i)*a[i];
		if(suml[i]+sumr[i]-a[i]>s)//選完以後,看看以哪個位置作爲最高點比較好 
		{
			s=suml[i]+sumr[i]-a[i];
			t=i;
		}
	}
	for(int i=t-1;i>0;i--)//向左更新隊列數據 
	{
		if(a[i]>a[i+1]) a[i]=a[i+1];
	}
	for(int i=t+1;i<=n;i++)//向右更新隊列數據 
	{
		if(a[i]>a[i-1]) a[i]=a[i-1];
	}
	for(int i=1;i<=n;i++)//輸出 
		cout<<a[i]<<" ";
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章