2019 南昌网络赛 I. Max answer

这题是poj2796的变形,用线段树来维护每个负数的对应的最小区间和

#include<iostream>
#include<stack>
#include<stdio.h>
using namespace std;
#define ls rt<<1
#define rs rt<<1|1
#define ll long long
const int maxn=5e5+100;
struct node
{
    int l,r;
    ll sum,minn,maxx;
    node(int l=0,int r=0,ll sum=0,ll minn=0,ll maxx=0)
    {
        this->l=l;
        this->r=r;
        this->sum=sum;
        this->minn=minn;
        this->maxx=maxx;
    }
}tree[maxn<<2];
int L[maxn],R[maxn],a[maxn],n;
ll pre[maxn],ans=-(5e10+10);
stack<int>sta;

void pushup(int rt)
{
    tree[rt].sum=tree[ls].sum+tree[rs].sum;
    tree[rt].minn=min(tree[ls].minn,tree[rs].minn);
    tree[rt].maxx=max(tree[ls].maxx,tree[rs].maxx);
}
void build(int rt,int l,int r)
{
    tree[rt].l=l,tree[rt].r=r;
    if(l==r)
    {
        tree[rt].sum=tree[rt].minn=tree[rt].maxx=pre[l];
        return ;
    }
    int mid=(l+r)>>1;
    build(ls,l,mid);
    build(rs,mid+1,r);
    pushup(rt);
}
ll queryminn(int rt,int l,int r)
{
    if(tree[rt].l>=l&&tree[rt].r<=r)
        return tree[rt].minn;
    int mid=(tree[rt].l+tree[rt].r)>>1;
    if(r<=mid)
        return queryminn(ls,l,r);
    else
        if(l>mid)
            return queryminn(rs,l,r);
        else
            return min(queryminn(ls,l,mid),queryminn(rs,mid+1,r));
}
ll querymaxx(int rt,int l,int r)
{
    if(tree[rt].l>=l&&tree[rt].r<=r)
        return tree[rt].maxx;
    int mid=(tree[rt].l+tree[rt].r)>>1;
    if(r<=mid)
        return querymaxx(ls,l,r);
    else
        if(l>mid)
            return querymaxx(rs,l,r);
        else
            return max(querymaxx(ls,l,mid),querymaxx(rs,mid+1,r));
}
int main()
{
    scanf("%d",&n);
    a[0]=-1e5-10;;
    a[n+1]=-1e5-10;
    for(int i=1;i<=n;i++) scanf("%d",&a[i]),pre[i]=pre[i-1]+a[i];
    build(1,1,n);
    for(int i=1;i<=n+1;i++)
    {
        if(sta.empty()||a[i]>=a[sta.top()])
            sta.push(i);
        else
        {
            while(!sta.empty()&&a[i]<a[sta.top()])
            {
                R[sta.top()]=i-1;
                sta.pop();
            }
            sta.push(i);
        }
    }
    sta.pop();
    for(int i=n;i>=0;i--)
    {
        if(sta.empty()||a[i]>=a[sta.top()])
            sta.push(i);
        else
        {
            while(!sta.empty()&&a[i]<a[sta.top()])
            {
                L[sta.top()]=i+1;
                sta.pop();
            }
            sta.push(i);
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(a[i]>=0)
            ans=max(ans,(pre[R[i]]-pre[L[i]-1])*a[i]);
        else
            ans=max(ans,(queryminn(1,i,R[i])-((L[i]==i)?pre[i-1]:querymaxx(1,L[i],i-1)))*a[i]);
    }
    printf("%lld\n",ans);
    return 0;
}

 

posted @ 2019-04-23 22:43  eason99  阅读(76)  评论(0编辑  收藏  举报