icpc 南昌邀请赛网络赛 Max answer
就是求区间和与区间最小值的积的最大值 但是a[i]可能是负的 这就很坑 赛后看了好多dalao的博客 终于a了
这个问题我感觉可以分为两个步骤
第一步是对于每个元素 以它为最小值的最大区间是什么
第二步是找出来在这个区间里面 最大的连续和多少
那么我们怎么找到第一步这个最大区间呢
可以先找这个元素左边第一个比他小的值的下标 和右边第一个比他小的值的下标 这两个下标确定了 最大区间就确定了
怎么找这个下标呢 暴力的话时间复杂度太高 是n^2 需要使用单调栈:
单调栈 顾名思义就是元素都是单调递增或者递减的栈 至于它有什么作用 接着往下看
假如有一个数组a: 3 5 1 6 2
用数组 L 表示a数组里的每一个元素 从自身位置 向左 第一个比它小的元素的位置
那么L就应该是: 0 1 0 3 3 (这里为了方便表示 我让a数组的下标从1开始标记 这样L数组里面 0 就表示左边的数都比他大 1 就表示第一个数比他小 以此类推)
那么我们怎么利用单调栈实现呢?
先将 a[0]赋值为一个极小值 -0x7ffffff,然后将0入栈
对于数组a的每一个元素 进行如下语句:
while(a[S.top()]>=a[i])
S.pop();
l[i] = S.top();
S.push(i);
while语句 保证了栈里面的数据是单调递减的
看不明白没有关系 让我们模拟一下:
i==1时 a[S.top]=a[0]=-0x7ffffff 不进入while循环
所以L[1]=0;
将1入栈 此时的栈:0 1(实际上我们比较的是a[i] 所以逻辑上来讲 此时的栈:a[0] a[1] 也就是 -0x7ffff 3 因为我们需要用到左边的下标值 所以是将下标入栈 这样既可以访问到下标所对应的值 也可以访问下标)
i==2时,a[S.top]=a[1]=3 小于5 还是不进入while循环
L[2]=S.top()=1
将2入栈 此时的栈:0 1 2(-0x7ffff 3 5 )
i==3时,a[S.top]=a[2]=5 大于1
S.pop(),a[S.top]=a[1]=3还是大于1
S.pop(),a[S.top]=a[0]=-0x7ffffff 小于1 结束循环
所以L[3]=0
将3入栈 此时的栈:0 3(-0x7ffff 1)
.........
以此类推
逻辑上栈中的元素(a[i])始终是递减的
这样我们就通过以此循环求出了L数组 也就是找到了之前说的 最大区间的左边界 找右边界也是一样的思路,只是循环的方向不同
好了现在我们完成了第一步 要进行第二步 也就是找每个区间里面的最大连续和(如果a[i]<0的话需要找最小连续和)
如果a[i]均为非负的话就很简单了 肯定是区间越长 连续和越大 但问题是a[i]是可以有负数的
那就需要分情况讨论了
我们可以开4个数组 lmax lmin rmax rmin
lmax 和 rmax 用来记录最大连续和的区间的左右下标
lmin 和 rmin 记录最小的和的左右下标
怎么更新这四个数组呢?
for(i=;i<=n;i++)
{
if(s[i-]-s[lmin[i-]-]>)
lmin[i]=i;
else
lmin[i]=lmin[i-];
if(s[i-]-s[lmax[i-]-]<)
lmax[i]=i;
else
lmax[i]=lmax[i-];
}
s[i]是前i项的和
看代码很容易理解 如果前面几项的和是正的 那就不要他 让lmin[i]=i 如果是负的 那么加上他 这样连续和就会变小
rmax和rmin只需要倒着更新就行
最后别忘了 这四个数组必须是在L数组和R数组的范围内的 相当于第一步是第二步的限制条件:
if(a[i]<)
{
ll=max(l[i]+,lmin[i]);
rr=min(r[i]-,rmin[i]);
}
else
{
ll=max(l[i]+,lmax[i]);
rr=min(r[i]-,rmax[i]);
}
完整ac代码:
#include<bits/stdc++.h> using namespace std; long long i,n,ll,rr,s[],a[],lmin[],lmax[],rmin[],rmax[],l[],r[],ans;
stack<long long> S; int main()
{
cin>>n;
for(i=;i<=n;i++)
{
cin>>a[i];
s[i]=s[i-]+a[i];
}
ans=a[]*a[];
S.push();
a[]=-0x7fffff;
a[n+]=-0x7fffff-;
for(i=;i<=n;i++)
{
while(a[S.top()]>=a[i])
S.pop();
l[i] = S.top();
S.push(i);
}
while(S.size())
S.pop();
S.push(n+);
for(i=n;i>=;i--)
{
while(a[S.top()]>=a[i])
S.pop();
r[i]=S.top();
S.push(i);
}
lmin[]=;
lmax[]=;
rmin[n]=n;
rmax[n]=n;
for(i=;i<=n;i++)
{
if(s[i-]-s[lmin[i-]-]>)
lmin[i]=i;
else
lmin[i]=lmin[i-];
if(s[i-]-s[lmax[i-]-]<)
lmax[i]=i;
else
lmax[i]=lmax[i-];
}
for(i=n-;i>=;i--)
{
if(s[rmin[i+]]-s[i]>)
rmin[i]=i;
else
rmin[i]=rmin[i+];
if(s[rmax[i+]]-s[i]<)
rmax[i]=i;
else
rmax[i]=rmax[i+];
}
for(i=;i<=n;i++)
{
if(a[i]<)
{
ll=max(l[i]+,lmin[i]);
rr=min(r[i]-,rmin[i]);
}
else
{
ll=max(l[i]+,lmax[i]);
rr=min(r[i]-,rmax[i]);
}
ans=max(ans,a[i]*(s[rr]-s[ll-]));
}
cout<<ans; }
icpc 南昌邀请赛网络赛 Max answer的更多相关文章
- 2019 ICPC南昌邀请赛网络赛比赛过程及题解
解题过程 中午吃饭比较晚,到机房lfw开始发各队的账号密码,byf开始读D题,shl电脑卡的要死,启动中...然后听到谁说A题过了好多,然后shl让blf读A题,A题blf一下就A了.然后lfw读完M ...
- icpc 南昌邀请赛网络赛 Subsequence
题目链接:https://nanti.jisuanke.com/t/38232 就是判断输入是不是子序列 没想到贡献了将近十几次罚时..........可以说是菜的真实了 用cin cout超时了 改 ...
- 2019 ICPC南昌邀请赛 网络赛 K. MORE XOR
说明 \(\oplus x\)为累异或 $ x^{\oplus(a)}$为异或幂 题意&解法 题库链接 $ f(l,r)=\oplus_{i=l}^{r} a[i]$ $ g(l,r)=\ ...
- 南昌邀请赛网络赛 D.Match Stick Game(dp)
南昌邀请赛网络赛 D.Match Stick Game 题目传送门 题目就会给你一个长度为n的字符串,其中\(1<n<100\).这个字符串是一个表达式,只有加减运算符,然后输入的每一个字 ...
- 计蒜客 38228. Max answer-线段树维护单调栈(The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer 南昌邀请赛网络赛) 2019ICPC南昌邀请赛网络赛
Max answer Alice has a magic array. She suggests that the value of a interval is equal to the sum of ...
- POJ-2796 & 2019南昌邀请赛网络赛 I. 区间最大min*sum
http://poj.org/problem?id=2796 https://nanti.jisuanke.com/t/38228 背景 给定一个序列,对于任意区间,min表示区间中最小的数,sum表 ...
- 2019ICPC南昌邀请赛网络赛 I. Max answer (单调栈+线段树/笛卡尔树)
题目链接 题意:求一个序列的最大的(区间最小值*区间和) 线段树做法:用单调栈求出每个数两边比它大的左右边界,然后用线段树求出每段区间的和sum.最小前缀lsum.最小后缀rsum,枚举每个数a[i] ...
- 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)
Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...
- 2019南昌邀请赛网络赛:J distance on the tree
1000ms 262144K DSM(Data Structure Master) once learned about tree when he was preparing for NOIP(N ...
随机推荐
- 【面试】吃透了这些Redis知识点,面试官一定觉得你很NB(干货 | 建议珍藏)
万字长文,干货满满. 是数据结构而非类型 很多文章都会说,redis支持5种常用的数据类型,这其实是存在很大的歧义.redis里存的都是二进制数据,其实就是字节数组(byte[]),这些字节数据是没有 ...
- 1.5准备CentOS和Nginx环境「深入浅出ASP.NET Core系列」
准备CentOS 1.1虚拟机 CentOS的安装这里使用vmware workstation 14来做虚拟机,当然你也可以用Oracle的虚拟机或者不用虚拟机,使用云服务或者使用双系统,不是什么大问 ...
- 兼容小程序的canvas画图组件jmGraph
基于CANVAS的简单画图组件让你用类似于dom的方式,在canvas上画图,感觉会不会很爽. 主页:http://graph.jm47.com/示例:http://graph.jm47.com/ex ...
- DS标签控件文本解析格式
DS标签控件使用DSL文本渲染引擎,支持DSL引擎代码.目前支持代码如下: <b>粗体</b> 以粗体显示 <i>斜体</i> 以斜体显示 <u& ...
- es6 generator函数
es6 新增了Generator函数,一种异步编程的解决方案 回顾一下,es6 提供了新的遍历方法,for of ,适用于各种数据集合,统一了遍历操作,原生支持for of 集合的数据集合有.数组,字 ...
- 升级WIN10 (9879)后IE无响应的解决办法
身为程序猿,当然有了新系统就要尝尝鲜,有WIN8时,哥是朋友圈第一个用的,有WIN8.1时哥也是第一个升级的. 现在WIN10来了,当然也得赶紧尝尝鲜.直接下载了 9879版的预览版本安装. 要说WI ...
- BestSync多终端文件资料同步利器
分享一款多终端文件同步的强力软件,windows下使用. 我这里的多终端意思是,多台电脑.移动存储.云端. 就我个人而言,实用性在于移动硬盘和电脑上都有的文件,比如保存项目资料,电脑上需要编辑,有时外 ...
- 长图的展开与收起(Android)
前言: 在app的文章中,经常会夹杂着一些特别长的长图.在阅读的时候需要滑动很久才能看图片下方的文字,因此对于长图只展示图片上面一部分,并且可以展开这个功能是很重要的. 效果: 基本思路: 利用sca ...
- RowKey设计之单调递增行键/时序数据
在一个集群中,一个导入数据的进程锁住不动,所有的client都在等待一个region (因而也就是一个单个节点),过了一会后,变成了下一个region…如果使用了单调递增 或者时序的key便会造成 ...
- 如何知道一个EXE使用什么开发语言开发的
一般是看EXE调用哪些DLL,这可以使用VC++中的工具Dependency Walker,它可以列出静态链接的所有DLL. 如果EXE中的DLL包括MSVBVM60.DLL,则是使用VB 6.0开发 ...