Codeforces Round #622(Div 2)C2. Skyscrapers (hard version)
题目链接 :
C2. Skyscrapers (hard version)
题目描述 :
与上一道题类似,只是数据范围变大, 5e5, 如果用我们原来的方法,铁定是超时的。
考察点 :
单调栈,贪心,前缀和,后缀和
析题得侃:
上面说了,用原先得方法得话是铁定超时的,那怎么优化呢?通过 easy version ,我们可以
得知合适的位置一定是由两部分组成的,左侧的数的和,右侧的数的和,我们求这些和的时候
也确实浪费了大量的时间,我们能否知道这个位置,然后直接得到这个位置的和呢?然后直接
取一下最大值。
我们知道左右两侧一定是单调的,那么既然是单调的,我们能不能用单调栈来维护呢?
显然是可以的。
怎么维护呢?
看一组数据 :
下标 : 1 2 3 4 5 6
数值 : 5 2 3 6 7 4 (假设现在都在左侧,还没有找到合适的中间位置)
我们发现 2 的左侧必须 <= 2,同样的, 4 的左侧必须 <= 4,但是 有些数本来就比 4 小
所以 pre[6] = pre[3] + a[6] * (6 - 3)
同理,后缀也是一样的,逆过来就可以了
接下来我们要求某个位置的和就是 : sum = pre[i] + suf[i + 1]
Code:
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 5e5 + 10;
typedef long long LL;
LL a[maxn],pre[maxn],suf[maxn];
LL L[maxn],R[maxn];
int n;
stack<int>S;
int main(void) {
scanf("%d",&n);
for(int i = 1; i <= n; i ++) {
scanf("%lld",&a[i]);
}
// 便于我们处理,可以先入栈一个 0
S.push(0);
for(int i = 1; i <= n; i ++) {
while(a[i] <= a[S.top()]) S.pop();
L[i] = S.top();
S.push(i);
}
while(!S.empty()) S.pop();
//同上
S.push(n + 1);
for(int i = n; i ; i --) {
while(a[i] <= a[S.top()]) S.pop();
R[i] = S.top();
S.push(i);
}
//计算每个位置的前缀和
for(int i = 1; i <= n; i ++) {
LL l = L[i];
pre[i] = pre[l] + a[i] * (i - l);
}
//计算每个位置的后缀和
for(int j = n; j ; j --) {
LL r = R[j];
suf[j] = suf[r] + a[j] * (r - j);
}
// 寻找合适的位置
LL sum = pre[1] + suf[2],id = 1;
for(int i = 1; i <= n; i ++ ) {
if(sum < pre[i] + suf[i + 1]) {
id = i;
sum = pre[i] + suf[i + 1];
}
}
for(int i = id - 1; i >= 1; i --) {
a[i] = min(a[i + 1],a[i]);
}
// 中间的那两个位置一定是 ok 的,我们需要从下一个开始
for(int j = id + 2; j <= n; j ++) {
a[j] = min(a[j - 1],a[j]);
}
for(int i = 1; i <= n; i ++) {
cout << a[i] << " ";
}
cout << endl;
return 0;
}
后记 :
优化往往是再复杂的基础上进行优化,根据某些性质,利用相应的数据结构进行优化。
Codeforces Round #622(Div 2)C2. Skyscrapers (hard version)的更多相关文章
- Codeforces Round #581(Div. 2)
Codeforces Round #581(Div. 2) CF 1204 A. BowWow and the Timetable 题解:发现,$4$的幂次的二进制就是一个$1$后面跟偶数个$0$. ...
- Codeforces Round #334(div.2)(新增不用二分代码) B
B. More Cowbell time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...
- Codeforces Round #334(div.2) A
A. Uncowed Forces time limit per test 1 second memory limit per test 256 megabytes input standard in ...
- codeforces Round #389(Div.2)C Santa Claus and Robot(思维题)
题目链接:http://codeforces.com/contest/752/problem/C 题意:给出一系列机器人的行动方向(机器人会走任意一条最短路径),问最少标记几个点能让机器人按这个 路径 ...
- Codeforces Round #626 (Div. 2) B. Count Subrectangles
题目连接:https://codeforces.com/contest/1323/problem/B 题意:给一个大小为n的a数组,一个大小为m的b数组,c数组是二维数组c[i][j]=a[i]*b[ ...
- Codeforces Round #342 (Div 2) 解题报告
除夕夜之有生之年CF第一场 下午从奶奶家回到姥姥家,一看还有些时间,先吃点水果陪姥姥姥爷聊了会儿,再一看表,5:20....woc已经开场20分钟了...于是抓紧时间乱搞.. **A. Guest F ...
- Codeforces Round 1153(div. 2)
这场奇差.ABCD四题.179名. 但是E在现场有213个人做出. 描述一下我在35分钟做完D后的心路历程. 首先看到这道E,第一下想到的是把所有的横向和竖向的整列(行)求出相连的个数. 然后想如何能 ...
- Codeforces Round #345 (Div 2)
最后两题是orzCJK学长帮忙代打的,不过总算是到蓝名了(上次睡迟了,只剩半个小时,结果作大死点开题目看,结果rating掉了100多),还有论代码风格的重要性!!!(没写空格被学长各种D) A题 题 ...
- Codeforces Round #556(Div.1)
A 容易发现i,i+1至少有一个数出现,于是可以让尽量多的2和奇数出现 #include<bits/stdc++.h> using namespace std; int n,s1,s2; ...
随机推荐
- 视觉slam十四讲ch5 joinMap.cpp 代码注释(笔记版)
#include <iostream> #include <fstream> using namespace std; #include <opencv2/core/co ...
- pycham设置头文件内容
pycharm软件 设置头文件方法 File->settings->Editor->File and Code Templates->Python Script #!/usr ...
- (六)mybatis拦截器
首先拦截器可以拦截mybatis四大核心对象:StatementHandler,ParameterHandler,ResultSetHandler,Executor,具体拦截时根据需求拦截一部分方法 ...
- 微信小程序开发技巧总结(二) -- 文件的选取、移动、上传和下载
微信小程序开发技巧总结(二) -- 文件的选取.移动.上传和下载 1.不同类型文件的选取 1.1 常用的图片 视频 对于大部分开发者来说,需要上传的文件形式主要为图片,微信为此提供了接口. wx.ch ...
- scala中符号的意思
1. => 定义函数, xxx => yyy 左边是函数变量,右边是函数返回值 2. <- 遍历中的<- 将变量赋给索引 for( i <- arrs ) 3. -> ...
- logstash 安装插件multiline
一.安装multiline 在使用elk 传输记录 java 日志时,如下 一个java的报错 在elk中会按每一行 产生多条记录,不方便查阅 这里修改配置文件 使用 multiline 插件 ...
- Linux Firewalld用法及案例
Firewalld概述 动态防火墙管理工具 定义区域与接口安全等级 运行时和永久配置项分离 两层结构 核心层 处理配置和后端,如iptables.ip6tables.ebtables.ipset和模块 ...
- mac chrome
command + < 可以直接跳转到谷歌设置的页面去.
- c语言double类型的输入
double输入用 %lf ,而不能用 %f 今天在使用double类型输入时先用了 scanf("%lf", &a),结果以%f输出的时候都是0,以%g,%e输出似乎是最 ...
- leetcode--js--Longest Substring Without Repeating Characters
问题描述: Given a string, find the length of the longest substring without repeating characters. Example ...