计蒜客 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 分析: 根据题意,就是比较斜率大小 只看一段区间的话,那么这段区间能看见的楼房数量就是这 ...
随机推荐
- Mysql表字段命令alter add
alter add命令用来增加表的字段. alter add命令格式:alter table 表名 add字段 类型 其他; 例如,在表MyClass中添加了一个字段passtest,类型为int(4 ...
- java之mybatis之缓存
1.mybatis自带缓存功能.分为一级缓存,二级缓存. 2.一级缓存为 session 缓存,在一个 session中 ,一个查询的 select 语句只会执行一次,根据 <select&g ...
- centos8安装chromium浏览器
1/yum install epel* [root@localhost framework]# yum list epl* Last metadata expiration check: 0:57:4 ...
- pandas-12 数学计算操作df.sum()、df.min()、df.max()、df.decribe()
pandas-12 数学计算操作df.sum().df.min().df.max().df.decribe() 常用的数学计算无非就是加减,最大值最小值,方差等等,pandas已经内置了很多方法来解决 ...
- 钻石diamaund外语
Whenever I fail as a father or husband... a toy and a diamond always works. I never worry about diet ...
- 二维码扫码登录原理及简单demo
扫码登录原理转载自: https://www.cnblogs.com/liyasong/p/saoma.html 需求介绍 首先,介绍下什么是扫码登录.现在,大部分同学手机上都装有qq和淘宝,天猫等这 ...
- django 的form登录 注册
#!/usr/bin/env python # -*- coding: utf8 -*- #__Author: "Skiler Hao" #date: 2017/3/30 15:4 ...
- spring Security的自定义用户认证
首先我需要在xml文件中声明.我要进行自定义用户的认证类,也就是我要自己从数据库中进行查询 <http pattern="/*.html" security="no ...
- Beta冲刺(2/7)——2019.5.23
所属课程 软件工程1916|W(福州大学) 作业要求 Beta冲刺(2/7)--2019.5.23 团队名称 待就业六人组 1.团队信息 团队名称:待就业六人组 团队描述:同舟共济扬帆起,乘风破浪万里 ...
- 关于jsp页面中name=“username”与name=“username ”的区别
我们可以仔细的观察一下,上面的name属性都等于username,但是确实存在大同小异的差距,为什么这样说呢,因为,第二个比第一个多了一个空格,在jsp中,我曾经遇到过一个情况就是两个单选按钮用同一个 ...