计蒜客 38228. Max answer-线段树维护单调栈(The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer 南昌邀请赛网络赛) 2019ICPC南昌邀请赛网络赛
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 \le n \le 5 \times 10 ^5n(1≤n≤5×105).
Second line contains nn integers represent the array a (-10^5 \le a_i \le 10^5)a(−105≤ai≤105).
Output
One line contains an integer represent the answer of the array.
样例输入复制
5
1 2 3 4 5
样例输出复制
36
用单调栈判断以每个值为最小值的最大左边界和右边界。后对对每个值分成负数和正数讨 论取可行区间内的最小或最大值,方法为求前缀和和后缀和,然后用线段树求区间最值。
线段树维护的时候,左区间维护后缀和,右区间维护前缀和,找的时候,在i值左边找后缀,在i值右边找前缀,然后交叉的部分就是满足的区间。

代码:
//I-线段树+单调栈
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=5e5+;
const int inf=0x3f3f3f3f; #define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1 int a[maxn],l[maxn],r[maxn];
ll pre[maxn],beh[maxn],maxl[maxn<<],minl[maxn<<],maxr[maxn<<],minr[maxn<<]; void pushup(int rt)
{
maxl[rt]=max(maxl[rt<<],maxl[rt<<|]);
minl[rt]=min(minl[rt<<],minl[rt<<|]);
maxr[rt]=max(maxr[rt<<],maxr[rt<<|]);
minr[rt]=min(minr[rt<<],minr[rt<<|]);
} void build(int l,int r,int rt)
{
if(l==r){
maxl[rt]=minl[rt]=beh[l];
maxr[rt]=minr[rt]=pre[l];
return ;
} int m=(l+r)>>;
build(lson);
build(rson);
pushup(rt);
} ll query(int op,int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R){
if (op==) return maxl[rt];
else if(op==) return minl[rt];
else if(op==) return maxr[rt];
else if(op==) return minr[rt];
} int m=(l+r)>>;
ll ret;
if(op==||op==){
ret=-inf;
if(L<=m) ret=max(ret,query(op,L,R,lson));
if(R> m) ret=max(ret,query(op,L,R,rson));
}
else if(op==||op==){
ret=inf;
if(L<=m) ret=min(ret,query(op,L,R,lson));
if(R> m) ret=min(ret,query(op,L,R,rson));
}
return ret;
} deque<int> deq;//因为是双端队列,所以插的时候要插到头上才能实现栈的功能 int main()
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=;i<=n;i++){
pre[i]=pre[i-]+a[i];
}
for(int i=n;i>=;i--){
beh[i]=beh[i+]+a[i];
}
build(,n,);
for(int i=;i<=n;i++){
while(deq.size()&&a[deq.front()]>=a[i]) deq.pop_front();
if(deq.empty()) l[i]=;
else l[i]=deq.front()+;
deq.push_front(i);
}
deq.clear();
for(int i=n;i>=;i--){
while(deq.size()&&a[deq.front()]>=a[i]) deq.pop_front();
if(deq.empty()) r[i]=n;
else r[i]=deq.front()-;
deq.push_front(i);
}
ll maxx=-inf,ret;
for(int i=;i<=n;i++){
if(a[i]>=){
ret=query(,l[i],i,,n,);
ret+=query(,i,r[i],,n,);
ret=ret-beh[i]-pre[i]+a[i];
ret*=a[i];
// cout<<query(1,l[i],i,1,n,1)<<" "<<query(3,i,r[i],1,n,1)<<endl;
}
else{
ret=query(,l[i],i,,n,);
ret+=query(,i,r[i],,n,);
ret=ret-beh[i]-pre[i]+a[i];
ret*=a[i];
}
maxx=max(maxx,ret);
}
printf("%lld\n",maxx);
}
计蒜客 38228. Max answer-线段树维护单调栈(The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer 南昌邀请赛网络赛) 2019ICPC南昌邀请赛网络赛的更多相关文章
- The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer (单调栈+线段树)
题目链接:https://nanti.jisuanke.com/t/38228 题目大意:一个区间的值等于该区间的和乘以区间的最小值.给出一个含有n个数的序列(序列的值有正有负),找到该序列的区间最大 ...
- The Preliminary Contest for ICPC China Nanchang National Invitational I.Max answer单调栈
题面 题意:一个5e5的数组,定义一个区间的值为 这个区间的和*这个区间的最小值,注意数组值有负数有正数,求所有区间中最大的值 题解:如果全是正数,那就是原题 POJ2796 单调栈做一下就ok 我们 ...
- 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)
Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...
- Max answer(The Preliminary Contest for ICPC China Nanchang National Invitational)
Alice has a magic array. She suggests that the value of a interval is equal to the sum of the values ...
- [CSP-S模拟测试]:陶陶摘苹果(线段树维护单调栈)
题目传送门(内部题116) 输入格式 第一行两个整数$n,m$,如题 第二行有$n$个整数表示$h_1-h_n(1\leqslant h_i\leqslant 10^9)$ 接下来有$m$行,每行两个 ...
- 洛谷 P4198 楼房重建 线段树维护单调栈
P4198 楼房重建 题目链接 https://www.luogu.org/problemnew/show/P4198 题目描述 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上 ...
- 【原创】tyvj1038 忠诚 & 计蒜客 管家的忠诚 & 线段树(单点更新,区间查询)
最简单的线段树之一,中文题目,不翻译.... 注释讲的比较少,这已经是最简单的线段树,如果看不懂真的说明最基础的理论没明白 推荐一篇文章http://www.cnblogs.com/liwenchi/ ...
- [计蒜客T2238]礼物_线段树_归并排序_概率期望
礼物 题目大意: 数据范围: 题解: 这题有意思啊($md$卡常 直接做怎么做? 随便上个什么东西,维护一下矩阵乘和插入,比如说常数还算小的$KD-Tree$(反正我是没见人过过 我们漏掉了一个条件, ...
- [BZOJ 2957]楼房重建(THU2013集训)(线段树维护单调栈)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2957 分析: 根据题意,就是比较斜率大小 只看一段区间的话,那么这段区间能看见的楼房数量就是这 ...
随机推荐
- Linux系统:保证数据安全落盘
在很多IO场景中,我们经常需要确保数据已经安全的写到磁盘上,以便在系统宕机重启之后还能读到这些数据.但是我们都知道,linux系统的IO路径还是很复杂的,分为很多层,每一层都可能会有buffer来加速 ...
- pandas-02 Series()和DataFrame()的区别与联系
pandas-02 Series()和DataFrame()的区别与联系 区别: series,只是一个一维数据结构,它由index和value组成. dataframe,是一个二维结构,除了拥有in ...
- Commander基本使用
随着NodeJs的不断发展,对于前端来说要做的东西也就更多,Vue脚手架React脚手架等等等一系列的东西都脱颖而出,进入到人们的视野当中,对于这些脚手架工具来讲也只是停留在应用阶段,从来没有想过脚手 ...
- Flask 进阶
OOP 面向对象反射 # __call__方法 # class Foo(object): # def __call__(self, *args, **kwargs): # return "i ...
- js 数组 深拷贝 复制 (汇总)
https://www.cnblogs.com/zhoupengyi/p/6048955.html https://www.cnblogs.com/racyily/p/3532176.html htt ...
- Flink源码分析 - 剖析一个简单的Flink程序
本篇文章首发于头条号Flink程序是如何执行的?通过源码来剖析一个简单的Flink程序,欢迎关注头条号和微信公众号"大数据技术和人工智能"(微信搜索bigdata_ai_tech) ...
- MySQL AutoIncrement--自增锁模式
自增锁模式 在MYSQL 5.1.22版本前,自增列使用AUTO_INC Locking方式来实现,即采用一种特殊的表锁机制来保证并发插入下自增操作依然是串行操作,为提高插入效率,该锁会在插入语句完成 ...
- ubuntu16.04+GTX2080Ti+torch7安装记录
环境说明 ubuntu16.04 cuda10.0 2080Ti显卡 拉取代码和修改编译脚本 拉取代码 用户先clone代码: git clone https://github.com/torch/d ...
- vsftp网络服务
1. vsftp概述 FTP是File Transfer Protocol(文本传输协议)的简称,用于Internet上的文件的双向传输.使用FTP传输时,具有一定程度的危险性,因为数据在因特网上面是 ...
- MySQL/MariaDB数据库的查询缓存优化
MySQL/MariaDB数据库的查询缓存优化 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.MySQL架构 Connectors(MySQL对外提供的交互接口,API): ...