当时我的第一想法也是用单调栈,但是被我写炸了;我也不知道错在哪里;

看了大神的写法,用数组模拟的;

记录下单调递增栈的下标,以及每个数字作为最小值的最左边的位置。

当有数据要出栈的时候,说明栈里的数据已经不是最小了,右端点就是当前位置-1,那么就可以计算栈顶的元素所作的贡献;出栈完后,当前这个数字,他的最左边就是栈顶所能到达的位置;入栈;

#include <bits/stdc++.h>using namespace std;const int maxn = 100000 + 5;
int a[maxn];
int stacks[maxn];
long long sum[maxn];
int lef[maxn];int main()
{freopen("feelgood.in","r",stdin);freopen("feelgood.out","w",stdout);int n;scanf("%d",&n);memset(sum,0,sizeof(sum));memset(lef,0,sizeof(lef));for(int i=1;i<=n;i++) {scanf("%d",&a[i]);sum[i] = sum[i-1] + a[i];}a[++n] = -1;int top = 0;long long ans = -1;int ansl = 0,ansr = 0;for(int i=1;i<=n;i++) {if(top==0||a[i]>a[stacks[top-1]]) {stacks[top++] = i;lef[i] = i;continue;}if(a[i]==a[stacks[top-1]])continue;while(top>=1&&a[i]<a[stacks[top-1]]) {top --;long long tmp = (long long)a[stacks[top]]*(sum[i-1]-sum[lef[stacks[top]]-1]);if(tmp>ans) {ansr = i-1;ansl = lef[stacks[top]];ans = tmp;}}lef[i] = lef[stacks[top]];stacks[top++] = i;}printf("%lld\n%d %d\n",ans,ansl,ansr);return 0;
}

View Code

(之前的错误找到了ans=-1,可以都为0)

 1 #include <bits/stdc++.h>
 2
 3 using namespace std;
 4
 5 int n;
 6 const int maxn = 100000+5;
 7 struct num {
 8     long long value;
 9     int maxleft,maxright;
10     int minleft,minright;
11     num():maxleft(1),maxright(1),minleft(1),minright(1){}
12 }a[maxn];
13
14 stack<pair<int,int> > S;
15
16 long long sum[maxn];
17
18 void getMax()
19 {
20     while(!S.empty())
21         S.pop();
22     S.push(make_pair(a[0].value,0));
23     for(int i=1;i<n;i++) {
24         while(!S.empty()&&S.top().first<=a[i].value) {
25             //int value = S.top().first;
26             int key = S.top().second;
27             S.pop();
28
29             a[i].maxleft +=a[key].maxleft;
30             if(!S.empty()) {
31                 a[S.top().second].maxright +=a[key].maxright;
32             }
33         }
34         S.push(make_pair(a[i].value,i));
35     }
36     while(!S.empty()) {
37         int key = S.top().second;
38         S.pop();
39         if(!S.empty()) {
40             a[S.top().second].maxright +=a[key].maxright;
41         }
42     }
43 }
44
45 void getMin()
46 {
47     while(!S.empty())
48         S.pop();
49     S.push(make_pair(a[0].value,0));
50     for(int i=1;i<n;i++) {
51         while(!S.empty()&&S.top().first>=a[i].value) {
52             //int value = S.top().first;
53             int key = S.top().second;
54             S.pop();
55
56             a[i].minleft +=a[key].minleft;
57             if(!S.empty()) {
58                 a[S.top().second].minright +=a[key].minright;
59             }
60         }
61         S.push(make_pair(a[i].value,i));
62     }
63     while(!S.empty()) {
64         int key = S.top().second;
65         S.pop();
66         if(!S.empty()) {
67             a[S.top().second].minright +=a[key].minright;
68         }
69     }
70 }
71
72 int main()
73 {
74     freopen("feelgood.in","r",stdin);
75     freopen("feelgood.out","w",stdout);
76     scanf("%d",&n);
77     for(int i=0;i<n;i++) {
78         scanf("%lld",&a[i].value);
79         sum[i+1] = sum[i] + a[i].value;
80     }
81    // getMax();
82     getMin();
83
84     int l = 0;
85     int r = 0;
86     long long ans = -1;
87     for(int i=0;i<n;i++) {
88         long long tmp = a[i].value*(sum[i+a[i].minright]-sum[i-a[i].minleft+1]);
89         if(ans<tmp) {
90             ans = tmp;
91             l = i - a[i].minleft + 2;
92             r = i + a[i].minright;
93         }
94     }
95
96     printf("%lld\n%d %d\n",ans,l,r);
97
98     return 0;
99 }

View Code

转载于:https://www.cnblogs.com/TreeDream/p/6937770.html

Gym - 101334F 单调栈相关推荐

  1. BZOJ1767/Gym207383I CEOI2009 Harbingers 斜率优化、可持久化单调栈、二分

    传送门--BZOJCH 传送门--VJ 注:本题在BZOJ上是权限题,在Gym里面也不能直接看,所以只能在VJ上交了-- 不难考虑到这是一个\(dp\). 设\(dep_x\)表示\(x\)在树上的带 ...

  2. POJ2796 Feel Good(单调栈)

    题意: 给出一列数据,要求一个区间内最小值与区间内数据总和乘积最大值 要点: 还是单调栈,这次我自己写的,先做了几题比较简单的果然还是有效果的,这题也是一样,按点遍历,网上大神做的是直接遍历一次即可, ...

  3. 【单调栈 前缀和 异或】7.21序列求和

    还要再细细思考的奇妙思路 题目描述 小A最近喜欢上了关于区间max的问题.她定义一个区间的价值是max(ai)(l<=i<=r)∗(alxoral+1xor...xorar)max(ai) ...

  4. 栈与队列7——单调栈结构(进阶问题)

    题目 一个含有重复值的数组arr,找到每一个i位置左边和右边离i位置最近且值比arr[i]小的位置,返回所有相应的信息. 举例:arr={3,4,1,5,6,2,7},返回如下的二维数组作为结果:{{ ...

  5. 栈与队列7——单调栈结构(初阶问题)

    题目 一个不含有重复值的数组arr,找到每一个i位置左边和右边离i位置最近且值比arr[i]小的位置,返回所有相应的信息. 举例:arr={3,4,1,5,6,2,7},返回如下的二维数组作为结果:{ ...

  6. 单调栈 or 线段树扫描线 ---- E. Delete a Segment [单调栈+二分] [扫描线处理空白位置的技巧乘2]

    题目链接 题目大意: 给出nnn个线段代表集合,现在问若可以将其中任意一个线段删除,则能够形成最多多少个独立的集合(取并集后) 解题思路1: 首先我们先对线段按照起点排序 那么我们枚举删除的线段iii ...

  7. 后缀数组 ---- 2018~2019icpc焦作H题[后缀数组+st表+二分+单调栈]

    题目链接 题目大意: 给出nnn个数,定义f[l,r]f[l,r]f[l,r]表示 区间[l,r][l,r][l,r]的最大值,求所有 子区间的最大值的和,要求相同的子区间只能算一次 比如数列 5 6 ...

  8. [Ahoi2013]差异[后缀数组+单调栈]

    链接 解题思路:很明显前面∑1<=i<j<=nlen(Ti)+len(Tj)\sum_{1<=i<j<=n}len(T_i)+len(T_j)∑1<=i< ...

  9. 【每日训练】2020/11/8(规律 + 二进制、单调栈 + 前缀和,后缀和、bitset + 枚举)

    整理的算法模板合集: ACM模板 目录 1. NC 打铁的箱子(规律 + 二进制) 2. NC 最优屏障(单调栈 + 前缀和,后缀和) 3. CF993C Careful Maneuvering(bi ...

最新文章

  1. 马斯克学什么计算机语言,马斯克头脑风暴——对计算机如醉如痴
  2. 不可能解开的谜题 (程序员修炼之道,评注者序)
  3. 多线程中Local Store Slot(本地存储槽)[转]
  4. php 去掉多维数组的键名,去除多维数组的最外层key 保留值
  5. ECCV 2020 | 微软亚洲研究院精选论文摘录
  6. Mr.J-- HTTP学习笔记(六)-- 代理
  7. C++:计算选手最终得分
  8. Spark学习之spark集群搭建
  9. java的import和python的import对比_Java中的Import和Pacakge作用生动详解(感觉python中的import作用差不多)...
  10. python 今日头条 控制手机_你知道Python脚本控制安卓手机可以用来做什么吗?
  11. 20155334 2016-2017-2 《Java程序设计》第三周学习总结
  12. Vb.net遍历一个窗口中的所有某类对象 (窗体中的控件) 的方法
  13. VHDL_EDA课设_八音电子琴
  14. php 登陆微博,用新浪微博账号登录(第三方登录)
  15. php学习笔记:登录练习(3)
  16. EXCEL 自动求和
  17. Linux环境下 微信支付退款 读取证书路径问题
  18. java图书商城项目_JavaWeb之网上图书商城-框架搭建
  19. UnityShader(四)基础光照
  20. 英语教师杂志英语教师杂志社英语教师编辑部2022年第16期目录

热门文章

  1. Archlinux 下的 VMWare Workstation 维护笔记
  2. backbone.js学习笔记
  3. 【手把手】JavaWeb 入门级项目实战 -- 文章发布系统 (第九节)
  4. cocos2dx在wp上使用自定义shader
  5. C和指针:第十三,十四章
  6. MATLAB“figure”使用详解
  7. C++引入名字空间(namespace)意义何在?为什么using namespace std会成为常用语句?
  8. Docker容器制作
  9. mysql中Bname表示什么_《MY SQL实用教程》期末考试题
  10. leetcode算法题--数组中重复的数字