uva1619 Feel Good

单调队列,滑动窗口

int t=0;
while(scanf("%d",&n)==1){
if(t)
printf(" "); //有点方便

单调队列用deque很方便
for(int i=1;i<=n;i++){ 维护单调队列
while(!q.empty()&&a[i]<=a[q.back()]){
R[q.back()]=i-1;
q.pop_back();
}
if(q.empty())L[i]=1;
else L[i]=q.back()+1;
q.push_back(i);
}
while(!q.empty()){
R[q.back()]=n;
q.pop_back();
}

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>
typedef long long LL;
using namespace std;
const int maxn=100010;
int n;
int a[maxn],L[maxn],R[maxn];//l[i]表示以a[i]为最小值的左半区间的最左边端点,r[i]表示以a[i]为最小值的右半区间的最右边端点
LL sum[maxn];

int main(){
    int t=0;
    while(scanf("%d",&n)==1){
        if(t)
            printf("
");
        t++;
        sum[0]=0;
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
      deque<int>q;
      for(int i=1;i<=n;i++){
        while(!q.empty()&&a[i]<=a[q.back()]){
            R[q.back()]=i-1;
            q.pop_back();
        }
        if(q.empty())L[i]=1;
        else L[i]=q.back()+1;
        q.push_back(i);
      }
      while(!q.empty()){
        R[q.back()]=n;
        q.pop_back();
      }
      LL ans=0;
      int ansL=1,ansR=1;
      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];
            ansL=L[i],ansR=R[i];
        }
      }
      printf("%lld
",ans);
      printf("%d %d
",ansL,ansR);
    }
return 0;
}
原文地址:https://www.cnblogs.com/lqerio/p/9747372.html