Skyscrapers (hard version) CodeForces - 1313C2(单调栈)

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.
思路:这个就不能暴力了,只能智取。我们要使结果最大,就要每一个都遍历一遍,但是不能像简单版本那样。因此我们用单调栈这个数据结构,可以直接计算出来。具体思路每个人可能不一样,主题思路就是单调栈。
代码如下:

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxx=5e5+100;
int a[maxx];
stack<int> head;
stack<int> tail;
int l[maxx],r[maxx];
ll L[maxx],R[maxx];
int n;

int main()
{
	scanf("%d",&n);a[0]=0;a[n+1]=0;
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
	{
		while(!head.empty()&&a[head.top()]>=a[i]) head.pop();//找左边第一个比自己小的
		if(head.empty()) l[i]=0;
		else l[i]=head.top();
		head.push(i);
	}
	for(int i=n;i>=1;i--)
	{
		while(!tail.empty()&&a[tail.top()]>=a[i]) tail.pop();//找右边第一个比自己小的
		if(tail.empty()) r[i]=n+1;
		else r[i]=tail.top();
		tail.push(i);
	}
	memset(L,0,sizeof(L));memset(R,0,sizeof(r));
	for(int i=1;i<=n;i++) L[i]=L[l[i]]+(ll)(i-l[i])*(ll)a[i];//计算这个数左边的和
	for(int i=n;i>=1;i--) R[i]=R[r[i]]+(ll)(r[i]-i)*(ll)a[i];//计算这个数右边的和
 	ll _max=0;int pos;
	for(int i=1;i<=n;i++)
	{
		if(L[i]+R[i]-a[i]>_max)
		{
			_max=L[i]+R[i]-(ll)a[i];//因为每一个都多算了一遍。
			pos=i;
		}
	}
	int k=pos;
	while(k>0)
	{
		for(int i=l[k]+1;i<=k-1;i++) a[i]=a[k];k=l[k];
	}
	k=pos;
	while(k<=n)
	{
		for(int i=k+1;i<=r[k]-1;i++) a[i]=a[k];k=r[k];
	}
	for(int i=1;i<=n;i++) cout<<a[i]<<" ";cout<<endl;
	return 0;
}

努力加油a啊,(o)/~

发布了502 篇原创文章 · 获赞 26 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/starlet_kiss/article/details/104599861
今日推荐