南昌邀请赛 III Max answers

题目链接:https://nanti.jisuanke.com/t/38228

解题思路:典型的单调栈问题,除了一个复数情况可能需要多考虑一下

单调栈讲解:https://www.cnblogs.com/violet-acmer/p/9780638.html

 

AC代码

#include 
#include
using namespace std;

const int maxn = 5e5+50;
long long sum[maxn];
int num[maxn];
int l[maxn];
int r[maxn];
long long minl[maxn];//往左找最小和
stacksta;

void init()
{
    while(!sta.empty())
        sta.pop();
}

int main()
{
    ios::sync_with_stdio(false);
    init();
    int n;
    cin >> n;
    sum[0] = 0;
    for(int i = 1; i <= n; ++i)
    {
        cin >> num[i];
        sum[i] = sum[i-1]+num[i];
    }
    for(int i = 1; i <= n; ++i)
    {
        while(!sta.empty() && num[sta.top()]>=num[i])
            sta.pop();
        l[i] = (sta.empty()?1:(sta.top()+1));
        sta.push(i);
    }
    init();
    for(int i = n; i >= 1; --i)
    {
        while(!sta.empty() && num[sta.top()]>=num[i])
            sta.pop();
        r[i] = (sta.empty()?n:(sta.top()-1));
        sta.push(i);
    }
    for(int i = 1; i <= n; ++i)
    {
        if(num[i] < 0)
        {
            for(int j = i; j >= l[i]; --j)
                minl[i] = min(minl[i], sum[i]-sum[j-1]);

        }
    }
    long long ans = 0;
    for(int i = 1; i <= n; ++i)
    {
        if(num[i] >= 0)
        {
            long long temp = sum[r[i]] - sum[l[i]-1];
            ans = max(ans, temp*num[i]);
        }
        else
        {
            long long minn = 0;
            for(int j = i+1; j <= r[i]; ++j)
                minn = min(minn, sum[j]-sum[i]);//往又找最小和
            ans = max(ans, num[i]*(minl[i]+minn));
            }
    }
    cout << ans << '\n';
    return 0;
}

 

你可能感兴趣的:(数据结构)