This is a harder version of the problem. In this version n≤500000n≤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 nn plots along the highway and is preparing to build nn 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 11 to nn . Then if the skyscraper on the ii -th plot has aiai floors, it must hold that aiai is at most mimi (1≤ai≤mi1≤ai≤mi ). Also there mustn't be integers jj and kk such that j<i<kj<i<k and aj>ai<akaj>ai<ak . Plots jj and kk are not required to be adjacent to ii .

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 nn (1≤n≤5000001≤n≤500000 ) — the number of plots.

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

Output

Print nn integers aiai  — 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][10,6,6] is optimal. Note that the answer of [6,6,8][6,6,8] also satisfies all restrictions, but is not optimal.

看到5e6的数据规模肯定不能O(n^2)暴力了,可以考虑单调栈。首先求出每个位置的最大左侧非递减序列和并存储到up[i](包括自己),可以用一个单调栈来维护。同理求出每个位置的最大右侧非递增序列和存到down[i],复杂度都为O(n).然后枚举每个位置,统计up[i]+down[i]-a[i](重复加了a[i],要减去一个),找到最大的一个位置往两边构造即可。注意这里单调栈的写法,我一开始直接用数组元素往里push,维护单调性时复杂度就可能很高,在第九个点T了...最后学习https://blog.csdn.net/weixin_44164153/article/details/104486676?fps=1&locationNum=2博客里的写法,改用数组下标往栈里push就能过了。

#include <bits/stdc++.h>
using namespace std;
long long a[],up[]={},down[]={},out[]={};//up[i]表示包括i最大非递减序列的和 比较up[i]+down[i]-a[i]即可(减去一个重复的)
int n;
int main()
{
cin>>n;
int i,j,k;
for(i=;i<=n;i++)scanf("%d",&a[i]);
stack<int>s;
s.push();
for(i=;i<=n;i++)
{
// if(a[i]>s.top())
// {
// up[i]=up[i-1]+a[i];
// //s.push(a[i]);
// s.push(i);
// }
// else
// {
// long long cnt=0,tot=0;
// while(s.size()&&s.top()>a[i])
// {
// tot+=s.top();
// cnt++;
// s.pop();
// }
// for(j=1;j<=cnt+1;j++)//出去的个数加上新进来的一个
// {
// s.push(a[i]);1
// }
// up[i]=a[i]*(cnt+1)+up[i-1]-tot;
while(s.size()&&a[s.top()]>=a[i])
{
s.pop();
}
up[i]=up[s.top()]+(i-s.top())*a[i];//有跨越的直接乘a[i]加过去即可
s.push(i);
// }
}
while(s.size())s.pop();
s.push(n+);//占位
for(i=n;i>=;i--)
{
// if(a[i]>s.top())
// {
// down[i]=down[i+1]+a[i];
// //s.push(a[i]);
// s.push(i);
// }
// else
// {
// long long cnt=0,tot=0;
// while(s.size()&&s.top()>a[i])
// {
// tot+=s.top();
// cnt++;
// s.pop();
// }
// for(j=1;j<=cnt+1;j++)//出去的个数加上新进来的一个
// {
// s.push(a[i]);
// }
// down[i]=a[i]*(cnt+1)+down[i+1]-tot;
while(s.size()&&a[s.top()]>=a[i])
{
s.pop();
}
down[i]=down[s.top()]+(s.top()-i)*a[i];
s.push(i);
// }
}
long long ans=,num=;
for(i=;i<=n;i++)
{
if(up[i]+down[i]-a[i]>ans)
{
ans=up[i]+down[i]-a[i];
num=i;
}
}
//构造输出序列
out[num]=a[num];
for(j=num-;j>=;j--)
{
out[j]=min(a[j],out[j+]);
}
for(j=num+;j<=n;j++)
{
out[j]=min(a[j],out[j-]);
}
for(i=;i<=n;i++)
{
cout<<out[i]<<' ';
}
return ;
}

Codeforces Round #622 C2.Skyscrapers (hard version)的更多相关文章

  1. Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version)(单调栈,递推)

    Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version) 题意: 你是一名建筑工程师,现给出 n 幢建筑的预计建设高度,你想建成峰状, ...

  2. Codeforces Round #622(Div 2)C2. Skyscrapers (hard version)

    题目链接 : C2. Skyscrapers (hard version) 题目描述 : 与上一道题类似,只是数据范围变大, 5e5, 如果用我们原来的方法,铁定是超时的. 考察点 : 单调栈,贪心, ...

  3. Codeforces Round #622 (Div. 2) B. Different Rules(数学)

    Codeforces Round #622 (Div. 2) B. Different Rules 题意: 你在参加一个比赛,最终按两场分赛的排名之和排名,每场分赛中不存在名次并列,给出参赛人数 n ...

  4. Codeforces Round #622 (Div. 2) A. Fast Food Restaurant(全排列,DFS)

    Codeforces Round #622 (Div. 2) A. Fast Food Restaurant 题意: 你是餐馆老板,虽然只会做三道菜,上菜时还有个怪癖:一位客人至少上一道菜,且一种菜最 ...

  5. Codeforces Round #622(Div 2) C1. Skyscrapers (easy version)

    题目链接: C1. Skyscrapers (easy version) 题目描述: 有一行数,使得整个序列满足 先递增在递减(或者只递增,或者只递减) ,每个位置上的数可以改变,但是最大不能超过原来 ...

  6. Codeforces Round #622 (Div. 2) 1313 C1

    C1. Skyscrapers (easy version) time limit per test1 second memory limit per test512 megabytes inputs ...

  7. Codeforces Round #622 (Div. 2).C2 - Skyscrapers (hard version)

    第二次写题解,请多多指教! http://codeforces.com/contest/1313/problem/C2 题目链接 不同于简单版本的暴力法,这个数据范围扩充到了五十万.所以考虑用单调栈的 ...

  8. Codeforces Round #622 (Div. 2) C2 - Skyscrapers (hard version) 单调栈

    从左往右扫,找到比第i个小的第一个数字,l[i] = l[last] + (i - last) * m[i],用单调栈O(n)维护这个过程,再从右往左扫,同理可以算出r数组,注意一下long long ...

  9. Codeforces Round #622 (Div. 2) C1. Skyscrapers (easy version)(简单版本暴力)

    This is an easier version of the problem. In this version n≤1000n≤1000 The outskirts of the capital ...

随机推荐

  1. loj6278 数列分块入门题2

    题意:支持区间加,询问区间中元素排名 维护两个域.一个域维护原序列,一个域维护快内排序序列. 每次修改后更新快内排序序列. 修改时O(sqrt(n)log(sqrt(n))) 询问时O(sqrt(n) ...

  2. [转]shallow heap & retained heap

    所有包含Heap Profling功能的工具(MAT, Yourkit, JProfiler, TPTP等)都会使用到两个名词,一个是Shallow Size,另一个是 Retained Size.  ...

  3. (转)java中新生代和老年代

    转自:http://blog.csdn.net/lojze_ly/article/details/49456255 聊聊JVM的年轻代 1.为什么会有年轻代 我们先来屡屡,为什么需要把堆分代?不分代不 ...

  4. nginx启动时指定配置文件

    下载源文件方式安装nginx 会在/usr/local目录下安装nginx 此时虚拟机系统中会有两个nginx 如果启动的时候没有指定配置文件的位置,默认读取的配置文件就是/usr/local/ngi ...

  5. Mysql多实例数据库安装应用

    第1章 MySQL多实例数据库企业级应用实践 1.1 MySQL多实例介绍 前文已经讲了为什么选择MySQL数据库,以及MySQL数据库在Linux系统下的多种安装方式,同时以单实例讲解了编译方式安装 ...

  6. 论Mac与windows的STS下的路径问题

    mac下的 <!-- javaBean生成在哪里 --> <javaModelGenerator targetPackage="com.atcrowdfunding.bea ...

  7. dgango 反射

    相关 """ 反射 由字符串反向找 变量.函数.类 """ import sys class Person(object): def __i ...

  8. HTML的表单初级验证

    HTML的表单初级验证 placeholder(提示信息) required(确保不能为空) pattern(正则表达式验证) 1. placeholder(提示信息) 语法: <p>账号 ...

  9. 复制文件或目录命令 - cp

    1) 命令名称:cp 2) 英文原意:copy 3) 命令所在路径:/bin/cp 4) 执行权限:所有用户 5) 功能描述:复制文件或目录 语法: cp -rp [原文件或目录][目标目录] -r ...

  10. 显示目录文件命令 - ls

    1) 命令名称:ls 2) 英文原意:list 3) 命令所在路径:/bin/ls 4) 执行权限:所有用户 5) 功能描述:显示目录文件 6) 语法: ls 选项[-ald][文件或目录] -a 显 ...