南昌网络赛 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 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上 ...
随机推荐
- Git config 配置文件
一.Git已经在你的系统中了,你会做一些事情来客户化你的Git环境.你只需要做这些设置一次:即使你升级了,他们也会绑定到你的环境中.你也可以在任何时刻通过运行命令来重新更改这些设置. Git有一个工具 ...
- POJ2195 Going Home (最小费最大流||二分图最大权匹配) 2017-02-12 12:14 131人阅读 评论(0) 收藏
Going Home Description On a grid map there are n little men and n houses. In each unit time, every l ...
- Tomcat 系统架构与设计模式1
从 Tomcat 如何分发请求.如何处理多用户同时请求,还有它的多级容器是如何协调工作的角度来分析 Tomcat 的工作原理,这也是一个 Web 服务器首要解决的关键问题 Tomcat 总体结构 To ...
- [翻译] FastReport Class Hierarchy (FastReport 组件类层次结构)
"TfrxComponent" is the base class for all FastReport components. Objects of this type have ...
- 使用google chrome抓取数据:抓取全国的高中的数据
http://tomycat.github.io/blog/other/2014/05/28/use-google-chrome-capture-data.html
- Selenium窗口切换-----Selenium快速入门(六)
有时候,我们打开多个窗口,进行多窗口操作,那么窗口间该如何切换呢? 切换的方法有两个,一个是通过窗口标题来验证,另一个是通过窗口特定的内容来验证,这两个方法都要求得到的标题或内容是唯一的. 用到的相关 ...
- Selenium下拉菜单(Select)的操作-----Selenium快速入门(五)
对于一般元素的操作,我们只要掌握本系列的第二,三章即可大致足够.对于下拉菜单(Select)的操作,Selenium有专门的类Select进行处理.文档地址为:http://seleniumhq.gi ...
- sql数据库 大小查询
select * from sys.master_files where name='CODA_PRD_Catalog' 12416*8/1024=(m)
- GO学习笔记 - 函数名前面是否有输入参数肯定是不一样的!!
在刚接触GO语言时候,我相信你也会有这种困惑,为什么有的函数名前面有输入参数,而一些却没有,它们是否有差别?确实有差别,没有输入参数,是一般的函数:有输入参数,是结构的方法,输入参数叫做“方法接收者” ...
- 洛谷P2664 树上游戏(点分治)
传送门 题解 因为一个sb错误调了一个晚上……鬼晓得我为什么$solve(rt)$会写成$solve(v)$啊!!!一个$O(logn)$被我硬生生写成$O(n)$了竟然还能过$5$个点……话说还一直 ...