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

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

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

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

#include <bits/stdc++.h>

using namespace std;

const int maxn =  + ;
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,,sizeof(sum));
memset(lef,,sizeof(lef)); for(int i=;i<=n;i++) {
scanf("%d",&a[i]);
sum[i] = sum[i-] + a[i];
} a[++n] = -;
int top = ;
long long ans = -;
int ansl = ,ansr = ;
for(int i=;i<=n;i++) {
if(top==||a[i]>a[stacks[top-]]) {
stacks[top++] = i;
lef[i] = i;
continue;
}
if(a[i]==a[stacks[top-]])
continue;
while(top>=&&a[i]<a[stacks[top-]]) {
top --;
long long tmp = (long long)a[stacks[top]]*(sum[i-]-sum[lef[stacks[top]]-]);
if(tmp>ans) {
ansr = i-;
ansl = lef[stacks[top]];
ans = tmp;
}
} lef[i] = lef[stacks[top]];
stacks[top++] = i; } printf("%lld\n%d %d\n",ans,ansl,ansr); return ;
}

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

 #include <bits/stdc++.h>

 using namespace std;

 int n;
const int maxn = +;
struct num {
long long value;
int maxleft,maxright;
int minleft,minright;
num():maxleft(),maxright(),minleft(),minright(){}
}a[maxn]; stack<pair<int,int> > S; long long sum[maxn]; void getMax()
{
while(!S.empty())
S.pop();
S.push(make_pair(a[].value,));
for(int i=;i<n;i++) {
while(!S.empty()&&S.top().first<=a[i].value) {
//int value = S.top().first;
int key = S.top().second;
S.pop(); a[i].maxleft +=a[key].maxleft;
if(!S.empty()) {
a[S.top().second].maxright +=a[key].maxright;
}
}
S.push(make_pair(a[i].value,i));
}
while(!S.empty()) {
int key = S.top().second;
S.pop();
if(!S.empty()) {
a[S.top().second].maxright +=a[key].maxright;
}
}
} void getMin()
{
while(!S.empty())
S.pop();
S.push(make_pair(a[].value,));
for(int i=;i<n;i++) {
while(!S.empty()&&S.top().first>=a[i].value) {
//int value = S.top().first;
int key = S.top().second;
S.pop(); a[i].minleft +=a[key].minleft;
if(!S.empty()) {
a[S.top().second].minright +=a[key].minright;
}
}
S.push(make_pair(a[i].value,i));
}
while(!S.empty()) {
int key = S.top().second;
S.pop();
if(!S.empty()) {
a[S.top().second].minright +=a[key].minright;
}
}
} int main()
{
freopen("feelgood.in","r",stdin);
freopen("feelgood.out","w",stdout);
scanf("%d",&n);
for(int i=;i<n;i++) {
scanf("%lld",&a[i].value);
sum[i+] = sum[i] + a[i].value;
}
// getMax();
getMin(); int l = ;
int r = ;
long long ans = -;
for(int i=;i<n;i++) {
long long tmp = a[i].value*(sum[i+a[i].minright]-sum[i-a[i].minleft+]);
if(ans<tmp) {
ans = tmp;
l = i - a[i].minleft + ;
r = i + a[i].minright;
}
} printf("%lld\n%d %d\n",ans,l,r); return ;
}

最新文章

  1. Windows下Python中pip安装Pillow报错总结(转载)
  2. 旋转V字俄罗斯方块
  3. 正则和xml解析
  4. 金融系列5《AUTH过程》
  5. 一种c#深拷贝方式完胜java深拷贝(实现上的对比)
  6. Java泛型方法定义及泛型类型推断
  7. HTML5 Canvas Text文本居中实例
  8. 使用stringstream对象简化类型转换
  9. Dynamics CRM 通过RetrieveEntityRibbonRequest和RetrieveApplicationRibbonRequest导出实体的Ribbon XML
  10. 【Python】SciKit-Learn包安装问题
  11. [svc]openssl对称非对称加密实战
  12. 教你一招:解决Win 10安装软件时提示:文件系统错误 (-1073740940)
  13. Sorting Algorithms
  14. vc6中向vs2010迁移的几个问题
  15. Notes of Daily Scrum Meeting(12.18)
  16. J2EE用监听器实现同一用户只能有一个在线
  17. java后台代码发送邮件
  18. svn版本分支及冲突解决笔记
  19. v-model实现
  20. C/C++比较容易搞混的一些写法

热门文章

  1. esper(4-4)-OverLapping Context
  2. 文献综述八:基于JAVA的商品网站的研究
  3. poi读取excel2010
  4. Hsl PLC
  5. nyoj 364——田忌赛马——————【贪心】
  6. Java网络编程二
  7. WPF-MVVM学习心德(WinForm转WPF心德)
  8. ireport 导出excel 分页 和 文本转数字格式的解决方法
  9. show与ShowDialog substring
  10. Java入门到精通——调错篇之Spring2.5利用aspect实现AOP时报错: error at ::0 can&#39;t find referenced pointcut XXX