南昌网络赛 I. Max answer (单调栈 + 线段树)
https://nanti.jisuanke.com/t/38228
题意
给你一个序列,对于每个连续子区间,有一个价值,等与这个区间和×区间最小值,
求所有子区间的最大价值是多少。
分析:我们先用单调栈预处理 区间 [L[i] , R[i] ] 最小值为a[i] , 的L[i] , R[i] ;
首先我们明白 , 如果a[i] >0 那 [L[i] , R[i] ] , 里面的数都是正数 , 所以应该全选 ;
a[i] < 0 , 那我们 应该在[L[i]-1 , i-1] 这里面找到前缀和最大 , 在[i,R[i]] 这里找到前缀和最小
这样的区间和才是最大
我。。。比赛的时候被自己秀死 , 判断a[i] >0 竟然也用了线段树的做法 , 导致边界没有控制好
#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <queue>
#define MAXN 500001
#define inf 0x3f3f3f3f using namespace std;
const int N=;
typedef long long ll; int a[N],L[N],R[N],s[N],top;
ll sum[N],ans=-0x7f7f7f7f,n,h[N];
ll l=,r=;
struct node{
int l,r;//区间[l,r] ll mx; //区间最大值
ll mn; //区间最小值
}tree[MAXN<<];//一定要开到4倍多的空间 void pushup(int index){ tree[index].mx = max(tree[index<<].mx,tree[index<<|].mx);
tree[index].mn = min(tree[index<<].mn,tree[index<<|].mn);
} int cnt;
void build(int l,int r,int index){
tree[index].l = l;
tree[index].r = r; if(l == r){
// scanf("%d",&tree[index].sum);
tree[index].mn = tree[index].mx =sum[++cnt];
return ;
}
int mid = (l+r)>>;
build(l,mid,index<<);
build(mid+,r,index<<|);
pushup(index);
} ll queryMIN(int l,int r,int index){
if(l <= tree[index].l && r >= tree[index].r){
//return tree[index].sum; return tree[index].mn;
} int mid = (tree[index].l+tree[index].r)>>; ll Min =0x7f7f7f7f;
if(l <= mid){ // Max = max(query(l,r,index<<1),Max);
Min = min(queryMIN(l,r,index<<),Min);
}
if(r > mid){ // Max = max(query(l,r,index<<1|1),Max);
Min = min(queryMIN(l,r,index<<|),Min);
}
//return ans; return Min;
//return Min;
}
ll queryMAX(int l,int r,int index){
if(l <= tree[index].l && r >= tree[index].r){
//return tree[index].sum;
return tree[index].mx;
//return tree[index].mn;
} int mid = (tree[index].l+tree[index].r)>>; ll Max = -0x7f7f7f7f; if(l <= mid){ Max = max(queryMAX(l,r,index<<),Max);
// Min = min(query(l,r,index<<1),Min);
}
if(r > mid){ Max = max(queryMAX(l,r,index<<|),Max);
//Min = min(query(l,r,index<<1|1),Min);
}
//return ans; return Max;
//return Min;
}
int main()
{ ios::sync_with_stdio(false);
cin>>n;
memset(sum,,sizeof(sum));
for(int i=;i<=n;i++)
{
cin>>a[i];
sum[i]=sum[i-]+a[i]; }
build(,n+,); top=;
for(int i=;i<=n;i++)
{
while(top&&a[s[top]]>=a[i])
--top;
L[i]=(top==?:s[top]+);
s[++top]=i;
}
top=;
for(int i=n;i>=;i--)
{
while(top&&a[s[top]]>=a[i])
--top;
R[i]=(top==?n:s[top]-);
s[++top]=i;
}
// cout<<queryMIN(2,2,1)<<endl;
for(int i=;i<=n;i++)
{
ll temp;
if(a[i]>)
{ temp =(sum[R[i]] - sum[L[i]-])*a[i];
// cout<<L[i]<<" "<<R[i]<<endl;
// cout<<queryMAX(i,R[i],1)<<" "<<queryMIN(L[i]-1,i-1,1)<<endl;
}
else if(a[i]<)
{ if(L[i]== && queryMAX(max(,L[i]-),max(,i-),)<)
temp=(queryMIN(i,R[i],))*a[i];
else
temp =(queryMIN(i,R[i],)-queryMAX(max(,L[i]-),max(,i-),))*a[i]; // cout<<queryMAX(L[i]-1,i-1,1)<<" "<<queryMIN(i,R[i],1)<<endl; }
else if(a[i]==)
temp=;
// else if(a[i]<0)
// {
// temp=(queryMIN(R[i],i,1) - queryMAX(L[i],i,1))*a[i];
// }
if(temp>ans) {ans=temp;}
} cout<<ans<<endl;
}
南昌网络赛 I. Max answer (单调栈 + 线段树)的更多相关文章
- 2019ICPC南昌邀请赛网络赛 I. Max answer (单调栈+线段树/笛卡尔树)
题目链接 题意:求一个序列的最大的(区间最小值*区间和) 线段树做法:用单调栈求出每个数两边比它大的左右边界,然后用线段树求出每段区间的和sum.最小前缀lsum.最小后缀rsum,枚举每个数a[i] ...
- 网络赛 I题 Max answer 单调栈+线段树
题目链接:https://nanti.jisuanke.com/t/38228 题意:在给出的序列里面找一个区间,使区间最小值乘以区间和得到的值最大,输出这个最大值. 思路:我们枚举每一个数字,假设是 ...
- 南昌邀请赛I.Max answer 单调栈+线段树
题目链接:https://nanti.jisuanke.com/t/38228 Alice has a magic array. She suggests that the value of a in ...
- The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer (单调栈+线段树)
题目链接:https://nanti.jisuanke.com/t/38228 题目大意:一个区间的值等于该区间的和乘以区间的最小值.给出一个含有n个数的序列(序列的值有正有负),找到该序列的区间最大 ...
- 南昌网络赛 I. Max answer 单调栈
Max answer 题目链接 https://nanti.jisuanke.com/t/38228 Describe Alice has a magic array. She suggests th ...
- 洛谷P4198 楼房重建 单调栈+线段树
正解:单调栈+线段树 解题报告: 传送门! 首先考虑不修改的话就是个单调栈板子题昂,这个就是 然后这题的话,,,我怎么记得之前考试好像有次考到了类似的题目昂,,,?反正我总觉着这方法似曾相识的样子,, ...
- 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)
2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...
- 2019南昌网络赛I:Yukino With Subinterval(CDQ) (树状数组套主席树)
题意:询问区间有多少个连续的段,而且这段的颜色在[L,R]才算贡献,每段贡献是1. 有单点修改和区间查询. 思路:46min交了第一发树套树,T了. 稍加优化多交几次就过了. 不难想到,除了L这个点, ...
- 2019南昌网络赛-I(单调栈+线段树)
题目链接:https://nanti.jisuanke.com/t/38228 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上 ...
随机推荐
- Error generating final archive: Unable to get debug signature key
在调试程序时,发生下面的错误: Error generating final archive: Unable to get debug signature key 解决办法: 删除下面的文件: C:\ ...
- Java设计模式(7)——装饰者模式
转载:http://blog.csdn.net/yanbober/article/details/45395747 一.装饰者模式的定义 装饰者( Decorator )模式又叫做包装模式.通过一种对 ...
- win2003 ent 64 + mssql ent 64
1.打win2003补丁(取消IE8.0)2.msconfig->boot.int->高级中,将内核改成83.将cd1,cd2,高到Servers,Tools目录中,并保证Servers, ...
- [GO]go context的deadline方法
package main import ( "time" "context" "fmt" ) func main() { d := time ...
- CodeForces 686B Little Robber Girl's Zoo (构造冒泡排序)
题意:给定一排列,让你通过一个区间交换的方式,完成排序. 析:这个题说了,最多不能超过20000次,而 n 最大才100,那么冒泡排序复杂度为 n * n,才10000,肯定是可以的,所以我们就模拟冒 ...
- NLog日志框架简写用法
本文转载:http://www.blogjava.net/qiyadeng/archive/2013/02/27/395799.html 在.net中也有非常多的日志工具,今天介绍下NLog.NLog ...
- JUnit4简易教程
1.下载JUnit4的jar包,在项目上右键选properties->Java Build Path ->Libraries->Add library添加刚才的jar包 2.在项目中 ...
- postgresql的日志实现机制
1.事务的概念 事务是从实际生活中引入数据库的一个概念,即事务内的操作,要么全做,要么全不做.就像银行转账一样,当从一个帐户转出一部分钱之后,就必须在另一个帐户中存入相同数目的钱,若是转出钱之后, ...
- archlinux 64bit 开发android
arch 64位下直接运行android emulator会出现错误:“Failed to start emulator: Cannot run program "xxxx/sdk/tool ...
- 控制 MediaElement(播放、暂停、停止、音量和速度)
控制 MediaElement(播放.暂停.停止.音量和速度) WPF中对于多媒体的支持非常完整,一般都是通过MediaElement来实现的. http://msdn.microsoft.com/z ...