南昌网络赛 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 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上 ...
随机推荐
- T31P电子秤数据读取
连接串口后先发送"CP\r\n"激活电子秤数据发送,收到的数据包是17字节的 using System; using System.Collections.Generic; usi ...
- Shell脚本传递带有空格的参数[摘录自网络]
参数处理 说明 $# 传递到脚本的参数个数 $* 以一个单字符串显示所有向脚本传递的参数 $$ 脚本运行的当前进程ID号 $! 后台运行的最后一个进程的ID号 $@ 与$#相同,但是使用时加引号,并在 ...
- Thrift结构分析及增加取客户端IP功能实现
目录 目录 1 1. 前言 1 2. 示例Service 1 3. 网络部分类图 2 4. 线程模式 3 4.1. IO线程 3 4.2. 工作线程 4 4.2.1. 工作线程类图 4 4.2.2. ...
- string 转换为枚举对应的值
public static Object Parse(Type enumType,string value) 例如:(Colors)Enum.Parse(typeof(Colors), "R ...
- Jquery 自定义插件写法(示例)
(function ($) { $.SmsHelper = $.SmsHelper || {}; $.extend($.SmsHelper, { //插件具体实现代码 yzmnum: 60, Ajax ...
- [LeetCode 题解]: Partition List
Given a linked list and a value x, partition it such that all nodes less than x come before nodes gr ...
- asp.net 导出 Excel 身份证格式显示格式问题
<%# Eval("数据").ToString()+" " %> 加上 Excel 中 不会显示科学计数法
- .NetCore分布式部署中的DataProtection密钥安全性
在.NetCore中默认使用DataProtection来保护数据,例如Cooike等.一般情况下DataProtection生成的密钥会被加密后存储,例如默认的文件存储 可以看到使用了Windows ...
- bash shell & 环境变量
root是没有~/.bashrc的,只. /etc/profile即可,/etc/profile和~/.bashrc的作用类似,只是作用域不同,都是写死的export,也有动态的脚本去设置命令和环境变 ...
- docker安装配置
########################################## #docker安装配置 #环境centos7 #配置docker阿里源 echo '#Docker [docker ...