2019 ICPC南昌邀请赛网络赛 - I Max answer

 --这个系列题解以后完善,持续更新,目前主要用于保存代码QWQ

这次好多都是原题升级版,然鹅眼熟又有什么用呢.jpg

这题是POJ2796升级版,我个人认为是一道很不错的题目。

单调栈+ST表,单调栈就不提,ST表可得当前点i的合法区间的rmq,对于负数点i,i点右边的min减去i点左边的max可得包含i点在内的最小子区间。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int topp,b[500005],c[500005],a[500005];
ll summ[500005],ffmax[500005][20],ffmin[500005][20];
struct node
{
    int num;
    int val;
}s[500005];
ll querymax(int l,int r)
{
    int k=log2(r-l+1);
    return max(ffmax[l][k],ffmax[r-(1<<k)+1][k]);
}
ll querymin(int l,int r)
{
    int k=log2(r-l+1);
    return min(ffmin[l][k],ffmin[r-(1<<k)+1][k]);
}
int main()
{
    int n,m,i,j,k,num,sum;
    ll ans;
//    while(~scanf("%d",&n))
//    {
        scanf("%d",&n);
        for(i=1;i<=n;i++)
            scanf("%lld",&a[i]);
        for(i=1;i<=n;i++)
            summ[i]=summ[i-1]+a[i];
        for(i=0;i<=n;i++)
            ffmin[i][0]=ffmax[i][0]=summ[i];
        for(i=1;(1<<i)<=n+1;i++)
        for(j=0;j+(1<<i)<=n+1;j++)
        {
            ffmax[j][i]=max(ffmax[j][i-1],ffmax[j+(1<<(i-1))][i-1]);
            ffmin[j][i]=min(ffmin[j][i-1],ffmin[j+(1<<(i-1))][i-1]);
        }
        for(i=1;i<=n;i++)
        {
            while(topp>=1&&s[topp].val>=a[i]) topp--;
            if(topp==0) b[i]=0;
            else b[i]=s[topp].num;
            s[++topp].num=i,s[topp].val=a[i];
        }
        topp=0;
        for(i=n;i>=1;i--)
        {
            while(topp>=1&&s[topp].val>=a[i]) topp--;
            if(topp==0) c[i]=n+1;
            else c[i]=s[topp].num;
            s[++topp].num=i,s[topp].val=a[i];
        }
        ans=-1e18;
        for(i=1;i<=n;i++)
        {
            if(a[i]>=0)
            ans=max(ans,a[i]*(summ[c[i]-1]-summ[b[i]]));
            else
            {
                ans=max(ans,(querymin(i,c[i]-1)-querymax(b[i],i-1))*(ll)a[i]);
            }
        }
        printf("%lld\n",ans);
//    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值