Gym - 101334F 单调栈
当时我的第一想法也是用单调栈,但是被我写炸了;我也不知道错在哪里;
看了大神的写法,用数组模拟的;
记录下单调递增栈的下标,以及每个数字作为最小值的最左边的位置。
当有数据要出栈的时候,说明栈里的数据已经不是最小了,右端点就是当前位置-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 单调栈相关推荐
- BZOJ1767/Gym207383I CEOI2009 Harbingers 斜率优化、可持久化单调栈、二分
传送门--BZOJCH 传送门--VJ 注:本题在BZOJ上是权限题,在Gym里面也不能直接看,所以只能在VJ上交了-- 不难考虑到这是一个\(dp\). 设\(dep_x\)表示\(x\)在树上的带 ...
- POJ2796 Feel Good(单调栈)
题意: 给出一列数据,要求一个区间内最小值与区间内数据总和乘积最大值 要点: 还是单调栈,这次我自己写的,先做了几题比较简单的果然还是有效果的,这题也是一样,按点遍历,网上大神做的是直接遍历一次即可, ...
- 【单调栈 前缀和 异或】7.21序列求和
还要再细细思考的奇妙思路 题目描述 小A最近喜欢上了关于区间max的问题.她定义一个区间的价值是max(ai)(l<=i<=r)∗(alxoral+1xor...xorar)max(ai) ...
- 栈与队列7——单调栈结构(进阶问题)
题目 一个含有重复值的数组arr,找到每一个i位置左边和右边离i位置最近且值比arr[i]小的位置,返回所有相应的信息. 举例:arr={3,4,1,5,6,2,7},返回如下的二维数组作为结果:{{ ...
- 栈与队列7——单调栈结构(初阶问题)
题目 一个不含有重复值的数组arr,找到每一个i位置左边和右边离i位置最近且值比arr[i]小的位置,返回所有相应的信息. 举例:arr={3,4,1,5,6,2,7},返回如下的二维数组作为结果:{ ...
- 单调栈 or 线段树扫描线 ---- E. Delete a Segment [单调栈+二分] [扫描线处理空白位置的技巧乘2]
题目链接 题目大意: 给出nnn个线段代表集合,现在问若可以将其中任意一个线段删除,则能够形成最多多少个独立的集合(取并集后) 解题思路1: 首先我们先对线段按照起点排序 那么我们枚举删除的线段iii ...
- 后缀数组 ---- 2018~2019icpc焦作H题[后缀数组+st表+二分+单调栈]
题目链接 题目大意: 给出nnn个数,定义f[l,r]f[l,r]f[l,r]表示 区间[l,r][l,r][l,r]的最大值,求所有 子区间的最大值的和,要求相同的子区间只能算一次 比如数列 5 6 ...
- [Ahoi2013]差异[后缀数组+单调栈]
链接 解题思路:很明显前面∑1<=i<j<=nlen(Ti)+len(Tj)\sum_{1<=i<j<=n}len(T_i)+len(T_j)∑1<=i< ...
- 【每日训练】2020/11/8(规律 + 二进制、单调栈 + 前缀和,后缀和、bitset + 枚举)
整理的算法模板合集: ACM模板 目录 1. NC 打铁的箱子(规律 + 二进制) 2. NC 最优屏障(单调栈 + 前缀和,后缀和) 3. CF993C Careful Maneuvering(bi ...
最新文章
- 马斯克学什么计算机语言,马斯克头脑风暴——对计算机如醉如痴
- 不可能解开的谜题 (程序员修炼之道,评注者序)
- 多线程中Local Store Slot(本地存储槽)[转]
- php 去掉多维数组的键名,去除多维数组的最外层key 保留值
- ECCV 2020 | 微软亚洲研究院精选论文摘录
- Mr.J-- HTTP学习笔记(六)-- 代理
- C++:计算选手最终得分
- Spark学习之spark集群搭建
- java的import和python的import对比_Java中的Import和Pacakge作用生动详解(感觉python中的import作用差不多)...
- python 今日头条 控制手机_你知道Python脚本控制安卓手机可以用来做什么吗?
- 20155334 2016-2017-2 《Java程序设计》第三周学习总结
- Vb.net遍历一个窗口中的所有某类对象 (窗体中的控件) 的方法
- VHDL_EDA课设_八音电子琴
- php 登陆微博,用新浪微博账号登录(第三方登录)
- php学习笔记:登录练习(3)
- EXCEL 自动求和
- Linux环境下 微信支付退款 读取证书路径问题
- java图书商城项目_JavaWeb之网上图书商城-框架搭建
- UnityShader(四)基础光照
- 英语教师杂志英语教师杂志社英语教师编辑部2022年第16期目录
热门文章
- Archlinux 下的 VMWare Workstation 维护笔记
- backbone.js学习笔记
- 【手把手】JavaWeb 入门级项目实战 -- 文章发布系统 (第九节)
- cocos2dx在wp上使用自定义shader
- C和指针:第十三,十四章
- MATLAB“figure”使用详解
- C++引入名字空间(namespace)意义何在?为什么using namespace std会成为常用语句?
- Docker容器制作
- mysql中Bname表示什么_《MY SQL实用教程》期末考试题
- leetcode算法题--数组中重复的数字