南昌邀请赛I.Max answer 单调栈+线段树
题目链接:https://nanti.jisuanke.com/t/38228
Alice has a magic array. She suggests that the value of a interval is equal to the sum of the values in the interval, multiplied by the smallest value in the interval.
Now she is planning to find the max value of the intervals in her array. Can you help her?
Input
First line contains an integer n(1≤n≤5×105).
Second line contains nn integers represent the array a (−105≤ai≤105).
Output
One line contains an integer represent the answer of the array.
样例输入复制
5
1 2 3 4 5
样例输出复制
36 题目定义区间的值为区间之和乘以区间的最小值,要你求出最大的区间值
求出前缀和sum并用线段树维护,再用单调栈求出第i个点之前第一个比他小的点l[i](下标),以及i之后第一个比他小的点r[i](下标)
枚举每个点,如果第i个点非负,区间值即为(sum[r[i]]-sum[l[i]-1])*a[i]
如果第i个点为负数则在[l[i],r[i]]内找到最小的区间和并乘以a[i]即为区间值
#include<iostream>
#include<stack>
using namespace std;
#define maxn 500005
#define ls l,mid,rt<<1
#define rs mid+1,r,rt<<1|1
#define ll long long
#define inf 0x3f3f3f3f
int n,l[maxn],r[maxn];
ll a[maxn],b[maxn],pre[maxn],sum[][maxn<<];
void pushup(int rt)
{
sum[][rt]=max(sum[][rt<<],sum[][rt<<|]);
sum[][rt]=min(sum[][rt<<],sum[][rt<<|]);
}
void build(int l,int r,int rt)
{
if(l==r)
{
sum[][rt]=sum[][rt]=pre[l];
return ;
}
int mid=l+r>>;
build(ls);
build(rs);
pushup(rt);
}
ll q1(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)return sum[][rt];
int mid=l+r>>;
ll ans=-inf;
if(L<=mid)ans=max(ans,q1(L,R,ls));
if(R>mid)ans=max(ans,q1(L,R,rs));
return ans;
}
ll q2(int L,int R,int l,int r,int rt)
{
if(L<=l&&R>=r)return sum[][rt];
int mid=l+r>>;
ll ans=inf;
if(L<=mid)ans=min(ans,q2(L,R,ls));
if(R>mid)ans=min(ans,q2(L,R,rs));
return ans;
}
int main()
{
cin>>n;
pre[]=;
for(int i=;i<=n;i++)
{
cin>>a[i];
pre[i]=pre[i-]+a[i];
}
build(,n,);
stack<int>s;
for(int i=;i<=n;i++)
{
while(s.size()&&a[s.top()]>=a[i])s.pop();
if(s.empty())l[i]=;
else l[i]=s.top()+;
s.push(i);
}
while(!s.empty())s.pop();
for(int i=n;i>=;i--)
{
while(s.size()&&a[s.top()]>=a[i])s.pop();
if(s.empty())r[i]=n;
else r[i]=s.top()-;
s.push(i);
}
ll ans=-inf;
for(int i=;i<=n;i++)
{
if(a[i]>=)ans=max(ans,(pre[r[i]]-pre[l[i]-])*a[i]);
else
{
ll maxx,minn;//maxx为[l[i]-1,i-1]的最大前缀和,minn为[i,r[i]]的最小前缀和,最小减最大负的就最多
maxx=q1(max(l[i]-,),max(i-,l[i]),,n,);
minn=q2(i,r[i],,n,);
ans=max(ans,(minn-maxx)*a[i]);
}
}
cout<<ans<<endl;
return ;
}
南昌邀请赛I.Max answer 单调栈+线段树的更多相关文章
- 2019ICPC南昌邀请赛网络赛 I. Max answer (单调栈+线段树/笛卡尔树)
题目链接 题意:求一个序列的最大的(区间最小值*区间和) 线段树做法:用单调栈求出每个数两边比它大的左右边界,然后用线段树求出每段区间的和sum.最小前缀lsum.最小后缀rsum,枚举每个数a[i] ...
- The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer (单调栈+线段树)
题目链接:https://nanti.jisuanke.com/t/38228 题目大意:一个区间的值等于该区间的和乘以区间的最小值.给出一个含有n个数的序列(序列的值有正有负),找到该序列的区间最大 ...
- 网络赛 I题 Max answer 单调栈+线段树
题目链接:https://nanti.jisuanke.com/t/38228 题意:在给出的序列里面找一个区间,使区间最小值乘以区间和得到的值最大,输出这个最大值. 思路:我们枚举每一个数字,假设是 ...
- 2018宁夏邀请赛 Continuous Intervals(单调栈 线段树
https://vjudge.net/problem/Gym-102222L 题意:给你n个数的序列,让判断有几个区间满足排完序后相邻两数差都不大于1. 题解:对于一个区间 [L,R],记最大值为 m ...
- 2019南昌网络赛-I(单调栈+线段树)
题目链接:https://nanti.jisuanke.com/t/38228 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上 ...
- 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)
2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...
- 洛谷P4198 楼房重建 单调栈+线段树
正解:单调栈+线段树 解题报告: 传送门! 首先考虑不修改的话就是个单调栈板子题昂,这个就是 然后这题的话,,,我怎么记得之前考试好像有次考到了类似的题目昂,,,?反正我总觉着这方法似曾相识的样子,, ...
- 南昌网络赛 I. Max answer (单调栈 + 线段树)
https://nanti.jisuanke.com/t/38228 题意给你一个序列,对于每个连续子区间,有一个价值,等与这个区间和×区间最小值,求所有子区间的最大价值是多少. 分析:我们先用单调栈 ...
- The Preliminary Contest for ICPC China Nanchang National Invitational I.Max answer单调栈
题面 题意:一个5e5的数组,定义一个区间的值为 这个区间的和*这个区间的最小值,注意数组值有负数有正数,求所有区间中最大的值 题解:如果全是正数,那就是原题 POJ2796 单调栈做一下就ok 我们 ...
随机推荐
- ubuntu10.04 搭建海思开发环境
(1)Ubuntu 10.04.4 LTS (Lucid Lynx) 下载地址:http://old-releases.ubuntu.com/releases/lucid/ (2)passwd roo ...
- Django 模本(Template--for--csrf--if--filter--simple_tag模版继承等)
前提 关于html寻找路线: template 如果在各个APP中存在, Django 会优先找全局template 文件下的html文件,如果全局下的template文件没有相关的html Dja ...
- Linux 总线、设备、驱动模型 与 设备树
1.总线.设备.驱动模型 本着高内聚.低耦合的原则,Linux 把设备驱动模型分为了总线.设备和驱动三个实体,这三个实体在内核里的职责分别如下: 设备和驱动向总线进行注册,总线负责把设备和对应的驱动绑 ...
- P1100 高低位交换
题目描述 给出一个小于2^{32}232的正整数.这个数可以用一个3232位的二进制数表示(不足3232位用00补足).我们称这个二进制数的前1616位为“高位”,后1616位为“低位”.将它的高低位 ...
- Django项目创建
一.创建方式 1.命令行创建: 2.pycharm创建项目: 二.创建MySQL数据库 三.修改配置文件链接数据库 修改python连接数据库方式 四.Django配置 1.添加app项目 2.修改h ...
- 一些java的demo
//1. false System.out.println(Integer.parseInt("01")>10); //2. abcdefghijklmnopqrstuvwx ...
- faiss索引基于数量级和内存限制的选择
它是一个能使开发者快速搜索相似多媒体文件的算法库.而该领域一直是传统的搜索引擎的短板.借助Faiss,Facebook 在十亿级数据集上创建的最邻近搜索(nearest neighbor search ...
- 聊聊 HashMap
数据存储底层? 数据底层具体存储是一个Node<K,V> HashMap 是基于哈希来映射的,那当映射冲突时候怎么解决? 链地址,数组+链表 HashMap 什么时候扩容? 负载因子 lo ...
- linux下open-vswitch安装卸载操作
一. ovs 从源码编译安装: 安装依赖项: ? 1 2 3 4 5 6 7 8 9 10 11 # apt install make # apt install gcc # apt install ...
- Linux中 ./configure --prefix命令
源码的安装一般由3个步骤组成:配置(configure).编译(make).安装(make install),具体的安装方法一般作者都会给出文档,这里主要讨论配置(configure).Configu ...