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 (单调栈 + 线段树)的更多相关文章

  1. 2019ICPC南昌邀请赛网络赛 I. Max answer (单调栈+线段树/笛卡尔树)

    题目链接 题意:求一个序列的最大的(区间最小值*区间和) 线段树做法:用单调栈求出每个数两边比它大的左右边界,然后用线段树求出每段区间的和sum.最小前缀lsum.最小后缀rsum,枚举每个数a[i] ...

  2. 网络赛 I题 Max answer 单调栈+线段树

    题目链接:https://nanti.jisuanke.com/t/38228 题意:在给出的序列里面找一个区间,使区间最小值乘以区间和得到的值最大,输出这个最大值. 思路:我们枚举每一个数字,假设是 ...

  3. 南昌邀请赛I.Max answer 单调栈+线段树

    题目链接:https://nanti.jisuanke.com/t/38228 Alice has a magic array. She suggests that the value of a in ...

  4. The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer (单调栈+线段树)

    题目链接:https://nanti.jisuanke.com/t/38228 题目大意:一个区间的值等于该区间的和乘以区间的最小值.给出一个含有n个数的序列(序列的值有正有负),找到该序列的区间最大 ...

  5. 南昌网络赛 I. Max answer 单调栈

    Max answer 题目链接 https://nanti.jisuanke.com/t/38228 Describe Alice has a magic array. She suggests th ...

  6. 洛谷P4198 楼房重建 单调栈+线段树

    正解:单调栈+线段树 解题报告: 传送门! 首先考虑不修改的话就是个单调栈板子题昂,这个就是 然后这题的话,,,我怎么记得之前考试好像有次考到了类似的题目昂,,,?反正我总觉着这方法似曾相识的样子,, ...

  7. 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)

    2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...

  8. 2019南昌网络赛I:Yukino With Subinterval(CDQ) (树状数组套主席树)

    题意:询问区间有多少个连续的段,而且这段的颜色在[L,R]才算贡献,每段贡献是1. 有单点修改和区间查询. 思路:46min交了第一发树套树,T了. 稍加优化多交几次就过了. 不难想到,除了L这个点, ...

  9. 2019南昌网络赛-I(单调栈+线段树)

    题目链接:https://nanti.jisuanke.com/t/38228 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上 ...

随机推荐

  1. [原创]使用OPENCC库进行简繁转换(C++代码)

    最近公司有一款游戏产品,字库存在问题,希望全自动进行简繁同屏自动转换的行为,减少工作量. 所以自己使用了WINDOWS自带的一些转换函数,但发现大量字出现异常,无法转换(测试iconv也发现无法转换) ...

  2. JQuery 对象和事件

    JQuery 对象和事件 一:JQuery 对象和 Dom 对象 在使用 JQuery 过程中,我们一般(也是绝大多数情况下,除非我们使用了第二个框架)只有两类对象,即:JQuery 对象和 Dom ...

  3. QQ互联

    [移动应用接入概述] QQ互联开放平台为第三方移动应用提供了丰富的API.第三方移动应用接入QQ互联开放平台后,即可通过调用平台提供的API实现用户使用QQ账号登录移动应用功能,且可以获取到腾讯QQ用 ...

  4. CoreDNS for kubernetes Service Discovery

    一.CoreDNS简介 Kubernetes包括用于服务发现的DNS服务器Kube-DNS. 该DNS服务器利用SkyDNS的库来为Kubernetes pod和服务提供DNS请求.SkyDNS2的作 ...

  5. 在Word 中撰写并发布到博客的帮助

    目前大部分的博客作者在用Word写博客这件事情上都会遇到以下3个痛点: 1.所有博客平台关闭了文档发布接口,用户无法使用Word,Windows Live Writer等工具来发布博客.使用Word写 ...

  6. [Selenium With C#基础教程] Lesson-03 超级链接

    作者:Surpassme 来源:http://www.jianshu.com/p/83809943e751 声明:本文为原创文章,如需转载请在文章页面明显位置给出原文链接,谢谢. 超级链接或链接是We ...

  7. HttpClient Timeout

    1. Overview This tutorial will show how to configure a timeout with the Apache HttpClient 4. If you ...

  8. leancloud js SDK 学习

    测试页面 AV.initialize("id", "key"); var TestObject = AV.Object.extend("TestObj ...

  9. [leetcode] 6. Balanced Binary Tree

    这个题目纠结了一会儿,终于从二叉树转化到AVL了.题目如下: Given a binary tree, determine if it is height-balanced. For this pro ...

  10. ISO in CSS content

    Name   Numeric Description Hex ISO in CSS content Octal       no-break space %A0 p:before { content: ...