题目链接:https://nanti.jisuanke.com/t/38228

题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值。

思路:比赛时还不会线段树,和队友在这题上弄了3小时,思路大体都是对的,但就是没法实现。这几天恶补线段树。

   首先可以利用单调栈来查找满足a[i]为最小值的最大区间L[i]~R[i]。然后利用线段树求一个段的和sum、最小前缀lsum和最小后缀rsum。然后遍历a[i]:

    a[i]>0:最优为sum(L[i],R[i])*a[i]

    a[i]<0:最优为(sumr(L[i],i)+suml(i,R[i]-i)*a[i]

   这里用线段树查询可以用传递引用来求lsum和rsum,因为我们查询一段区间是从左向右查询的,或者可以用三个全局变量Sum、Lsum、Rsum记录当前已找到的区间的对应属性也行。

AC代码:

#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=;
typedef long long LL; struct node{
int l,r;
LL sum,lsum,rsum; //sum为区间和,lsum最小前缀,rsum最小后缀
}tr[maxn<<];
//L[i]~R[i]为满足a[i]为最小的最大区间
int n,p,a[maxn],L[maxn],R[maxn],stk[maxn];
LL ans; node gets(node a,node b){
node t;
t.l=a.l,t.r=b.r;
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 v,int l,int r){
tr[v].l=l,tr[v].r=r;
if(l==r){
tr[v].sum=a[r];
tr[v].lsum=min(a[r]*1LL,0LL);
tr[v].rsum=min(a[r]*1LL,0LL);
return;
}
int mid=(l+r)>>;
build(v<<,l,mid);
build(v<<|,mid+,r);
tr[v]=gets(tr[v<<],tr[v<<|]);
} void query(node &x,int v,int l,int r){
if(l<=tr[v].l&&r>=tr[v].r){
x=gets(x,tr[v]);
return;
}
int mid=(tr[v].l+tr[v].r)>>;
if(l<=mid) query(x,v<<,l,r);
if(r>mid) query(x,v<<|,l,r);
} int main(){
scanf("%d",&n);
for(int i=;i<=n;++i)
scanf("%d",&a[i]);
a[]=a[n+]=0xcfcfcfcf;
stk[p=]=; //利用单调栈求L[i],R[i]
for(int i=;i<=n;++i){
while(a[stk[p]]>=a[i]) --p;
L[i]=stk[p]+;
stk[++p]=i;
}
stk[p=]=n+;
for(int i=n;i>=;--i){
while(a[stk[p]]>=a[i]) --p;
R[i]=stk[p]-;
stk[++p]=i;
}
build(,,n);
for(int i=;i<=n;++i){
if(a[i]>){
node t;
t.sum=t.lsum=t.rsum=;
query(t,,L[i],R[i]);
if(a[i]*t.sum>ans) ans=a[i]*t.sum;
}
else if(a[i]<){
LL tmp=;
node t;
t.sum=t.lsum=t.rsum=;
query(t,,L[i],i);
tmp+=t.rsum;
t.sum=t.lsum=t.rsum=;
query(t,,i,R[i]);
tmp+=t.lsum;
tmp-=a[i];
if(tmp*a[i]>ans) ans=tmp*a[i];
}
}
printf("%lld\n",ans);
return ;
}

最新文章

  1. mysql 主从
  2. C# winform 上传文件到服务器
  3. Java 常见异常及趣味解释
  4. Keil C51.uew
  5. 对象作为 handleEvent
  6. Windows Server2012R2 添加Microsoft .NET Framework 3.5 功能失败的解决方法
  7. TkbmMWClientQuery的计算字段在CalcFields事件触发次数太多
  8. Eclipse安装TestNG插件
  9. C#程序以管理员权限运行(ZT)
  10. http_proxy_module模块常用参数
  11. IdentityServer4 中文文档 -5- (简介)支持和咨询选项
  12. 【hexo】01安装
  13. thinkphp error:no database select
  14. C# 如何防止重放攻击(转载)
  15. 修改hosts文件的脚本1.0
  16. node.js之express中app.use
  17. codevs 2173 忠诚
  18. gpu 显卡 本质
  19. LVS+keepalived+nginx
  20. VS2013中全局属性与局部属性的设置

热门文章

  1. SfMLearner 记录
  2. Linux系统编程——fcntl
  3. Access denied when I try to install profiler
  4. spark2.1源码分析1:Win10下IDEA源码阅读环境的搭建
  5. ftp服务器使用-windowsftp服务起搭建
  6. 名称 ****不是有效的标识符 sql
  7. [java 2019-04-09] 代码生成word文档中的表格嵌套问题
  8. python configparse模块&amp;xml模块
  9. sql server 报错处理
  10. python的str.format方法