2019ICPC南昌邀请赛网络赛 I. Max answer (单调栈+线段树/笛卡尔树)
题意:求一个序列的最大的(区间最小值*区间和)
线段树做法:用单调栈求出每个数两边比它大的左右边界,然后用线段树求出每段区间的和sum、最小前缀lsum、最小后缀rsum,枚举每个数a[i],设以a[i]为最小值的区间为[l,r]
若a[i]>0,则最优解就是a[i]*([l,r]的区间和),因为[l,r]上的数都比a[i]大。
若a[i]<0,则最优解是a[i]*([l,i-1]上的最小后缀+a[i]+[i+1,r]上的最小前缀),在线段树上查询即可。
复杂度$O(nlogn)$
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+,inf=0x3f3f3f3f;
int a[N],n,sta[N],L[N],R[N],tp;
#define ls (u<<1)
#define rs (u<<1|1)
#define mid ((l+r)>>1)
struct D {ll sum,lsum,rsum;} s[N<<];
D mg(D a,D b) {
D t= {,};
t.sum=a.sum+b.sum;
t.lsum=min(a.lsum,a.sum+b.lsum);
t.rsum=min(b.rsum,b.sum+a.rsum);
return t;
}
void build(int u=,int l=,int r=n) {
if(l==r) {s[u].sum=a[l],s[u].lsum=min((ll)a[l],0ll),s[u].rsum=min((ll)a[l],0ll); return;}
build(ls,l,mid),build(rs,mid+,r),s[u]=mg(s[ls],s[rs]);
}
void qry(int L,int R,D& x,int u=,int l=,int r=n) {
if(l>=L&&r<=R) {x=mg(x,s[u]); return;}
if(l>R||r<L)return;
qry(L,R,x,ls,l,mid),qry(L,R,x,rs,mid+,r);
}
int main() {
scanf("%d",&n);
a[]=a[n+]=~inf;
for(int i=; i<=n; ++i)scanf("%d",&a[i]);
sta[tp=]=;
for(int i=; i<=n; ++i) {
for(; a[sta[tp]]>=a[i]; --tp);
L[i]=sta[tp]+,sta[++tp]=i;
}
sta[tp=]=n+;
for(int i=n; i>=; --i) {
for(; a[sta[tp]]>=a[i]; --tp);
R[i]=sta[tp]-,sta[++tp]=i;
}
build();
ll ans=;
for(int i=; i<=n; ++i) {
if(a[i]>) {
D t= {,};
qry(L[i],R[i],t);
ans=max(ans,a[i]*t.sum);
} else if(a[i]<) {
ll x=;
D t= {,};
qry(L[i],i,t);
x+=t.rsum;
t= {,};
qry(i,R[i],t);
x+=t.lsum;
x-=a[i];
ans=max(ans,a[i]*x);
}
}
printf("%lld\n",ans);
return ;
}
笛卡尔树做法:对整个序列建立笛卡尔树,用和线段树相同的方法求出每个结点的子树所代表区间的sum,lsum,rsum,枚举每个结点,如果是正数则乘上该结点的sum,如果是负数则乘上该结点的(左儿子的rsum+右儿子的lsum+结点本身的值)即可。
复杂度$O(n)$
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5e5+,inf=0x3f3f3f3f;
int n,a[N],ls[N],rs[N],sta[N],tp;
ll sum[N],lsum[N],rsum[N];
void build() {
a[n+]=~inf,sta[tp=]=n+;
for(int i=; i<=n; ++i) {
for(; a[i]<a[sta[tp]]; --tp);
ls[i]=rs[sta[tp]],rs[sta[tp]]=i,sta[++tp]=i;
}
}
void dfs(int u) {
if(!u)return;
dfs(ls[u]),dfs(rs[u]);
sum[u]=sum[ls[u]]+a[u]+sum[rs[u]];
lsum[u]=min(lsum[ls[u]],sum[ls[u]]+a[u]+lsum[rs[u]]);
rsum[u]=min(rsum[rs[u]],sum[rs[u]]+a[u]+rsum[ls[u]]);
}
int main() {
scanf("%d",&n);
for(int i=; i<=n; ++i)scanf("%d",&a[i]);
build(),dfs(rs[n+]);
ll ans=;
for(int i=; i<=n; ++i) {
if(a[i]>)ans=max(ans,a[i]*sum[i]);
else if(a[i]<)ans=max(ans,a[i]*(rsum[ls[i]]+a[i]+lsum[rs[i]]));
}
printf("%lld\n",ans);
return ;
}
2019ICPC南昌邀请赛网络赛 I. Max answer (单调栈+线段树/笛卡尔树)的更多相关文章
- 计蒜客 38228. Max answer-线段树维护单调栈(The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer 南昌邀请赛网络赛) 2019ICPC南昌邀请赛网络赛
Max answer Alice has a magic array. She suggests that the value of a interval is equal to the sum of ...
- 南昌邀请赛I.Max answer 单调栈+线段树
题目链接:https://nanti.jisuanke.com/t/38228 Alice has a magic array. She suggests that the value of a in ...
- 网络赛 I题 Max answer 单调栈+线段树
题目链接:https://nanti.jisuanke.com/t/38228 题意:在给出的序列里面找一个区间,使区间最小值乘以区间和得到的值最大,输出这个最大值. 思路:我们枚举每一个数字,假设是 ...
- The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer (单调栈+线段树)
题目链接:https://nanti.jisuanke.com/t/38228 题目大意:一个区间的值等于该区间的和乘以区间的最小值.给出一个含有n个数的序列(序列的值有正有负),找到该序列的区间最大 ...
- 2019南昌邀请赛网络预选赛 I. Max answer(单调栈+暴力??)
传送门 题意: 给你你一序列 a,共 n 个元素,求最大的F(l,r): F(l,r) = (a[l]+a[l+1]+.....+a[r])*min(l,r); ([l,r]的区间和*区间最小值,F( ...
- 南昌邀请赛网络赛 D.Match Stick Game(dp)
南昌邀请赛网络赛 D.Match Stick Game 题目传送门 题目就会给你一个长度为n的字符串,其中\(1<n<100\).这个字符串是一个表达式,只有加减运算符,然后输入的每一个字 ...
- icpc 南昌邀请赛网络赛 Max answer
就是求区间和与区间最小值的积的最大值 但是a[i]可能是负的 这就很坑 赛后看了好多dalao的博客 终于a了 这个问题我感觉可以分为两个步骤 第一步是对于每个元素 以它为最小值的最大区间是什么 第二 ...
- 南昌网络赛 I. Max answer 单调栈
Max answer 题目链接 https://nanti.jisuanke.com/t/38228 Describe Alice has a magic array. She suggests th ...
- 南昌网络赛 I. Max answer (单调栈 + 线段树)
https://nanti.jisuanke.com/t/38228 题意给你一个序列,对于每个连续子区间,有一个价值,等与这个区间和×区间最小值,求所有子区间的最大价值是多少. 分析:我们先用单调栈 ...
随机推荐
- 自学Java测试代码一数据类型、数组使用
2017-08-22 21:23:37. writer:pprp package test; public class helloWorld { int maxn = 123; //常量,需要定义一个 ...
- Mysql事物的4种隔离级别
SQL标准定义了4种隔离级别,包括了一些具体规则,用来限定事务内外的哪些改变是可见的,哪些是不可见的. 低级别的隔离级一般支持更高的并发处理,并拥有更低的系统开销. 首先,我们使用 test 数据库, ...
- HDU 5773 The All-purpose Zero(O(nlgn)求LIS)
http://acm.hdu.edu.cn/showproblem.php?pid=5773 题意: 求LIS,其中的0可以看做任何数. 思路: 因为0可以看做任何数,所以我们可以先不管0,先求一遍L ...
- [Vue]Vue语法糖v-bind、v-on
语法糖 :是指在不影响功能的情况下,添加某种方法实现同样的效果,从而方便程序开发,简化代码是书写. Vue.js的v-bind和v-on指令都提供了语法糖,也可以说是缩写. 1.v-bind可以省略, ...
- zabbix自动化运维学习笔记(服务器安装)
最近博主开始接触自动化运维.首先就是zabbix这个开源的监控系统 一开始博主只是在自己的虚拟机上尝试安装.最后终于开始在公司的服务器上正式安装,教程博主也是通过度娘找的 这是原文:链接 安装环境:C ...
- VS2017 MVC项目,新建控制器提示未能加载文件或程序集“Dapper.Contrib解决方法
VS2017中MVC项目中,右键新建控制器时,提示 未能加载文件或程序集“Dapper.Contrib, Version=1.50.0.0, Culture=neutral, PublicKeyTok ...
- gem doorkeeper(4000✨) ,Go-rails视频
博客OAuth教程:https://i.cnblogs.com/EditPosts.aspx?postid=9531091 doorkeeper: (4000
- Kotlin------数据类型和语法
今天简单的来介绍Kotlin的基本语法.编程语言大多相通的,会基础学起来都很快,理论都一样,实现的代码语言不一样而已. 数值类型 Kotlin 处理数值的方法和 java 很相似,但不是完全一样.比如 ...
- ArcMap加载在线地图
SimpleGIS 小小的SimpleGIS除了提供6大地图让人喜爱之外,更有其他的能耐同样让你爱不释手. 功能1:作为出图底图地图提供商中Bing.天地图两家提供的地图是无偏移的地图,所以可直接应用 ...
- AsyncCallback 异步回调委托
js是单线程语言,单线程就意味着,所有任务需要排队,前一个任务结束,才会执行后一个任务.如果前一个任务耗时很长,后一个任务就不得不一直等着. 如果排队是因为计算量大,CPU忙不过来,倒也算了,但是很多 ...