Codeforces Round #622 C2.Skyscrapers (hard version)
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
5
1 2 3 2 1
1 2 3 2 1
3
10 6 8
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)的更多相关文章
- Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version)(单调栈,递推)
Codeforces Round #622 (Div. 2) C2. Skyscrapers (hard version) 题意: 你是一名建筑工程师,现给出 n 幢建筑的预计建设高度,你想建成峰状, ...
- Codeforces Round #622(Div 2)C2. Skyscrapers (hard version)
题目链接 : C2. Skyscrapers (hard version) 题目描述 : 与上一道题类似,只是数据范围变大, 5e5, 如果用我们原来的方法,铁定是超时的. 考察点 : 单调栈,贪心, ...
- Codeforces Round #622 (Div. 2) B. Different Rules(数学)
Codeforces Round #622 (Div. 2) B. Different Rules 题意: 你在参加一个比赛,最终按两场分赛的排名之和排名,每场分赛中不存在名次并列,给出参赛人数 n ...
- Codeforces Round #622 (Div. 2) A. Fast Food Restaurant(全排列,DFS)
Codeforces Round #622 (Div. 2) A. Fast Food Restaurant 题意: 你是餐馆老板,虽然只会做三道菜,上菜时还有个怪癖:一位客人至少上一道菜,且一种菜最 ...
- Codeforces Round #622(Div 2) C1. Skyscrapers (easy version)
题目链接: C1. Skyscrapers (easy version) 题目描述: 有一行数,使得整个序列满足 先递增在递减(或者只递增,或者只递减) ,每个位置上的数可以改变,但是最大不能超过原来 ...
- Codeforces Round #622 (Div. 2) 1313 C1
C1. Skyscrapers (easy version) time limit per test1 second memory limit per test512 megabytes inputs ...
- Codeforces Round #622 (Div. 2).C2 - Skyscrapers (hard version)
第二次写题解,请多多指教! http://codeforces.com/contest/1313/problem/C2 题目链接 不同于简单版本的暴力法,这个数据范围扩充到了五十万.所以考虑用单调栈的 ...
- Codeforces Round #622 (Div. 2) C2 - Skyscrapers (hard version) 单调栈
从左往右扫,找到比第i个小的第一个数字,l[i] = l[last] + (i - last) * m[i],用单调栈O(n)维护这个过程,再从右往左扫,同理可以算出r数组,注意一下long long ...
- 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 ...
随机推荐
- yolov3 进化之路,pytorch运行yolov3,conda安装cv2,或者conda安装找不到包问题
yolov3 进化之路,pytorch运行yolov3,conda安装cv2,或者conda安装找不到包问题 conda找不到包的解决方案. 目前是最快最好的实时检测架构 yolov3进化之路和各种性 ...
- windows上快速新建1g的文件
在E盘新建1g文件 fsutil file createnew d:\b.txt 1073741824
- 转载:openmax基本概念
https://yellowmax.blog.csdn.net/article/details/78080168 https://yellowmax.blog.csdn.net/article/det ...
- 记录 Docker 的学习过程 (日志篇)
日志收集 elk 在node3上操作 docker pull sebp/elk:5610 node3# sysctl vm.max_map_count=262144 node3# docker run ...
- [USACO12FEB] 附近的牛 Nearby Cows - 树形dp,容斥
给你一棵 \(n\) 个点的树,点带权,对于每个节点求出距离它不超过 \(k\) 的所有节点权值和 \(m_i\) 随便定一个根,设\(f[i][j]\)表示只考虑子树,距离为\(j\)的权值和,\( ...
- (转) maven snapshot和release版本的区别
在使用maven过程中,我们在开发阶段经常性的会有很多公共库处于不稳定状态,随时需要修改并发布,可能一天就要发布一次,遇到bug时,甚至一 天要发布N次.我们知道,maven的依赖管理是基于版本管理的 ...
- RN开发-Navigator
1.在入口组件render方法中返回<Navigator> let defaultName = 'Welcome'; let defaultCo ...
- Centos 修改yum源为aliyun
修改服务器源,避免长途跋涉到国外: 位置: vim /etc/yum.repos.d/CentOS-Base.repo aliyun地址: 设置aliyun的yum源 wget -O /etc/yu ...
- Harvard's CS50
最近看了哈佛大学David主讲的计算机科学入门,给我一个最大的感受是计算机编程语言真的不重要,重要的是编程者的思想. 1.同一个问题可以就Scratch解决,也可以用C,用Python,用JavaSc ...
- 0120 springboot集成Mybatis和代码生成器
在日常开发中,数据持久技术使用的架子使用频率最高的有3个,即spring-jdbc , spring-jpa, spring-mybatis.详情可以看我之前的一篇文章spring操作数据库的3个架子 ...