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 ...
随机推荐
- (填坑系列) 用aio写server与client进行通信的坑
最近闲来无事,就估摸着自己写个“服务注册中心”来玩,当然因为是个人写的,所以一般都是简洁版本. 代码地址在:https://gitee.com/zhxs_code/my-service-registe ...
- 记录 Docker 的学习过程 (网络篇之跨主机互通)
下面从node3上操作node3# docker run -d -p 8500:8500 --name consul progrium/consul -server -bootstrap node3# ...
- 1.什么是 Docker
官网地址:https://www.docker.com/ Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud ...
- [转]shallow heap & retained heap
所有包含Heap Profling功能的工具(MAT, Yourkit, JProfiler, TPTP等)都会使用到两个名词,一个是Shallow Size,另一个是 Retained Size. ...
- 任务调度问题(贪心) hdu4864
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4864 The company hopes to maximize the number of the t ...
- python dataframe筛选列表的值转为list【常用】
网上方法参差不齐,无注释解释不好秒懂,没有自己想要的,故自己试验一番~ 1. 筛选列表中,当b列中为’1’时,所有c的值,然后转为list 2 .筛选列表中,当a列中为'one',b列为'1'时,所有 ...
- shell脚本编程学习笔记(一)
一.脚本格式 vim shell.sh #!/bin/bash //声明脚本解释器,这个‘#’号不是注释,其余是注释 #Program: //程序内容说明 #History: //时间和作者 二.sh ...
- CodeForces 1141A
https://vjudge.net/problem/CodeForces-1141A #include <bits/stdc++.h> using namespace std; int ...
- 【PAT甲级】1117 Eddington Number (25分)
题意: 输入一个正整数N(<=100000),接着输入N个非负整数.输出最大的整数E使得有至少E个整数大于E. AAAAAccepted code: #define HAVE_STRUCT_TI ...
- 修改oracle数据库用户名和密码
第一步:连接数据库 使用ssh工具以root身份连接服务器, 然后切换到oracle用户:su - oracle(回车) 使用sqlplus连接数据库:sqlplus /nolog(回车) 以管理员身 ...