51nod 1254 最大子段和 V2 ——单调栈
第1行:整数序列的长度N(2 <= N <= 50000)
第2 - N + 1行:N个整数(-10^9 <= A[i] <= 10^9)
输出交换一次后的最大子段和。
7
-2
11
-4
13
-5
-2
4
28
——————————————————————————————
这道题可以做到O(n) 但是瓶颈在读入
—————————————————————————————— 这道题 我们可以枚举右端点
这个我们先强制我们换的数只能是右端点后面的数(之后把数组倒过来再来一次就可以了)
维护一波后缀和(s【i】表示i-n的和)以及后缀最大值 (mx【i】表示i-n的mx)
那么我们枚举右端点之后 目的自然是求 到i的后缀和s【l】 减去 l到i的区间的最小值(min【l,r】) 的最优解
答案就是s【l】-min【l,r】-s【i+1】+mx【i+1】
那么因为 -s【i+1】+mx【i+1】已知
我们要维护的就是s【l】-mn【l,r】
我们可以利用单调栈维护每个mn所能占领的区间
这样就把数列分成了若干个区间 然后维护区间max(s【l】)
根据每个区间的情况记录最优解 很明显最优解只会越来越优
这样我们每次移动右端点的时候 就用当前端点的值v【i】去弹出栈的元素
然后更新新的区间的信息就好了
#include<stdio.h>
#include<cstring>
#include<algorithm>
#define LL long long
using namespace std;
const int M=;
const LL inf=1e15;
char buf[*M],*ptr=buf-;
int read(){
int ans=,f=,c=*++ptr;
while(c<''||c>''){if(c=='-') f=-; c=*++ptr;}
while(c>=''&&c<=''){ans=ans*+(c-''); c=*++ptr;}
return ans*f;
}
int n;
LL c[M],v[M],s[M],mx[M],mxh,ans;
int cnt;
struct node{LL mn,h;}q[M];
void solve(){
mxh=-inf; cnt=;
for(int i=n;i;i--) s[i]=s[i+]+v[i],mx[i]=max(mx[i+],v[i]);
for(int i=;i<=n;i++){
LL nowh=s[i];
while(cnt&&q[cnt].mn>=v[i]) nowh=max(nowh,q[cnt].h),cnt--;
q[++cnt].mn=v[i]; q[cnt].h=nowh;
mxh=max(mxh,nowh-v[i]); ans=max(ans,mxh-s[i+]+mx[i+]);
}
}
int main(){
fread(buf,,sizeof(buf),stdin);
n=read();
for(int i=;i<=n;i++) v[i]=read(); v[n+]=-inf;
for(int i=n;i;i--) s[i]=s[i+]+v[i],mx[i]=max(mx[i+],v[i]);
solve();
reverse(v+,v++n);
solve();
printf("%lld\n",ans);
return ;
}
51nod 1254 最大子段和 V2 ——单调栈的更多相关文章
- 51nod 1254 最大子段和 V2
N个整数组成的序列a[1],a[2],a[3],…,a[n],你可以对数组中的一对元素进行交换,并且交换后求a[1]至a[n]的最大子段和,所能得到的结果是所有交换中最大的.当所给的整数均为负数时和为 ...
- [多校联考2019(Round 4 T2)][51nod 1288]汽油补给(ST表+单调栈)
[51nod 1288]汽油补给(ST表+单调栈) 题面 有(N+1)个城市,0是起点N是终点,开车从0 -> 1 - > 2...... -> N,车每走1个单位距离消耗1个单位的 ...
- 51nod 1102 面积最大的矩形 (单调栈)
链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1102 思路: 首先介绍下单调栈的功能:利用单调栈,可以找到从左/ ...
- 【bzoj5089】最大连续子段和 分块+单调栈维护凸包
题目描述 给出一个长度为 n 的序列,要求支持如下两种操作: A l r x :将 [l,r] 区间内的所有数加上 x : Q l r : 询问 [l,r] 区间的最大连续子段和. 其中,一 ...
- 51nod 1215 数组的宽度(单调栈)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1215 题意: 思路: 计算出以第i个数为最大值的区间范围,l_max[i ...
- 51nod 最大M子段和系列
1052 最大M子段和 N个整数组成的序列a[1],a[2],a[3],…,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M >= N个数中正数的个数,那么输出所 ...
- 51nod 1437 迈克步(单调栈)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1437 题意: 思路: 单调栈题.求出以每个数为区间最大值的区间范围即可. ...
- 51nod 1102 面积最大的矩形(单调栈)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1102 题意: 思路: 做法就是求出每个长方形向左向右所能延伸的最大距离. ...
- 51nod 1215 单调栈/迭代
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1215 1215 数组的宽度 题目来源: Javaman 基准时间限制:1 ...
随机推荐
- ubuntu下安装redis及在php中使用
一.安装redis sudo apt-get install redis-server 安装完成后,Redis服务器会自动启动,我们可以通过下面的命令行检查一下: # redis-cli > p ...
- 【个人笔记】关于C++小数的处理
无论是C-Style还是C++-Style的输出,小数都会四舍五入.如果想要截断两种比较好的方法.第一种:利用sscanf输出成字符串,再人为地putchar().第二种:已知钦定保留6位小数,那么可 ...
- 再见NullPointerException。在Kotlin里null的处理(KAD 19)
作者:Antonio Leiva 时间:Apr 4, 2017 原文链接:https://antonioleiva.com/nullity-kotlin/ 关于Kotlin最重要的部分之一:无效处理, ...
- 从传统IT快速走向公共云计算
2年前有篇报道,说Facebook的每个运维同学至少能管理2万台服务器,这在当时的国内互联网引起了很大震动,按照传统IT的理解,每个运维同学能管理200台服务器已经很了不起了. 这些年来云计算发展非常 ...
- zabbix 语音告警
之前的文章中已经实现了zabbix 邮件告警和微信告警,生产环境上测试出消息抵达很及时,但是!万一服务器在大半夜突发故障微信.邮件这些通知都是废物了,大晚上还能听到微信通知吗?显然不可能(我的某朋友就 ...
- 剑指offer-跳台阶08
题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). class Solution: def jumpFloor(self, ...
- z 变换
1. z 变换 单位脉冲响应为 \(h[n]\) 的离散时间线性时不变系统对复指数输入 \(z^n\) 的响应 \(y[n]\) 为 \[ \tag{1} y[n] = H(z) z^{n}\] 式中 ...
- postgres(pl/pgsql)
复制后期看 https://www.cnblogs.com/stephen-liu74/archive/2012/06/06/2312759.html https://www.cnblogs.com/ ...
- linux下easy_install的安装与使用详解
Python中的easy_install工具用起来非常好用,它的作用类似于Php中的pear,或者Ruby中的gem,或者Perl中的cpan. 1.easy_install安装 如果想使用easy_ ...
- C++ Profiler工具之初体验
http://www.cnblogs.com/likwo/archive/2012/12/20/2826988.html 转 http://www.cnblogs.com/lenolix/archiv ...
