博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【单调栈,单调队列】总结
阅读量:4673 次
发布时间:2019-06-09

本文共 1413 字,大约阅读时间需要 4 分钟。

整天做DP太累了……下午重新看了下有关单调栈的内容

单调栈用途就在于求一个数列中,某点左侧第一个比他大(或小)的元素位置

假设维护一个单调上升的栈。如果入栈元素小于栈顶那么就要开始pop。而pop掉的元素一定全都大于这个入栈元素。单调栈内的两个相邻元素a,b如果在原序列中不是相邻的,则意味着b的出现pop掉了中间的元素,因此这中间的元素必定都大于b。

可以把单调栈的一个元素看做原序列的一块元素。b就代表了原序列中(a,b]

一个元素的进入弹掉了一部分元素,由此求出最左延伸量。如果一个元素即将被pop,意味着终于出现了一个比它小的,就可以求出最右延伸量了。

一个元素仅能进一次出一次,复杂度$O(n)$。

 

#include 
#include
#include
#define int long longusing namespace std;inline int read(){ int x(0),w(1); char c = getchar(); while(c^'-' && (c<'0'||c>'9')) c = getchar(); if(c == '-') w = -1, c = getchar(); while(c>='0' && c<='9') x = (x<<3) + (x<<1) + c - '0', c = getchar(); return x*w;}int n,a[100010],s[100010],top,l[100010],r[100010],sum[100010],L,R,ans=-0x3f3f3f3f;signed main(){// freopen(".in","r",stdin); n = read(); for(int i = 1; i <= n; ++i){ a[i] = read(); sum[i] = sum[i-1] + a[i]; } for(int i = 1; i <= n; ++i){ while(a[s[top]] > a[i] && top > 0){ r[s[top]] = i-1; --top; } l[i] = s[top]+1; s[++top] = i; } while(top){ r[s[top]] = n; --top; } for(int i = 1; i <= n; ++i){ if(ans < (sum[r[i]]-sum[l[i]-1])*a[i]){ ans = (sum[r[i]]-sum[l[i]-1])*a[i]; L = l[i], R = r[i]; } } printf("%lld\n%lld %lld",ans,L,R); return 0;}

 

转载于:https://www.cnblogs.com/qixingzhi/p/10825713.html

你可能感兴趣的文章
[ACM] POJ 1068 Parencodings(模拟)
查看>>
Drools只执行一个规则或者执行完当前规则之后不再执行其他规则(转)
查看>>
20180110小测
查看>>
冰点还原8.57 官方中文版下载
查看>>
poj 2236(并查集的应用)
查看>>
C 栈 链式存储
查看>>
Java 游戏报错 看不懂求教
查看>>
APP自动化测试
查看>>
HTML中让表单input等文本框为只读不可编辑的方法
查看>>
nodejs做中间层,向后端取数据
查看>>
IntelliJ IDEA 2017 MySQL5 绿色版 Spring 4 Mybatis 3 配置步骤详解(二)
查看>>
(转)Java DecimalFormat 用法(数字格式化)
查看>>
hiho_100_八数码
查看>>
Eclipse序列号生成代码
查看>>
JVM
查看>>
设计模式记录
查看>>
SPF,DSPF,RDPF,SPEF and SBPF.
查看>>
JS学习文章
查看>>
window系统服务器,远程连接mysql数据库。
查看>>
CAS总结之Ticket篇
查看>>