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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值