1 solutions

  • 0
    @ 2026-1-16 15:22:24

    /* 本题的知识点就是前缀和+单调队列。

    其中我们要找的就是连续子区间的最大值和连续子区间的最小值。所以我们需要维护两个单调队列,一个维护前缀和的最小值,一个维护前缀和的最大值。

    当维护前缀和的最小值的时候,当前位置的前缀和-前面最小的前缀和就是到当前位置最大的子区间和。

    代码如下: ———————————————— 版权声明:本文为CSDN博主「weixin_66009678」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_66009678/article/details/136812639

    */

    #include <bits/stdc++.h>
    using namespace std;
    #define print(x) std::cout<<#x<<'='<<(x)<<endl;
    const int N=3e5+5;
    typedef long long ll;
    ll ans;
    int a[N];
    int n,c;
    ll s[N];//前缀和
     
    ll solve1()//求连续子区间的最大值,然后*C,再返回总和
    {
        deque<int> q;//存前缀和的最小值
        q.push_back(0);
        ll sum=0;
        int l,r;//最大值对应的连续子区间的左右端点
        l=0;
        r=0;
        for(int i=1;i<=n;i++)
        {
            while(q.empty()==0&&s[i]<=s[q.back()])
            {
                q.pop_back();
            }
            if(q.empty()==0)
            {
                if(sum<(s[i]-s[q.front()]))
                {
                    sum=s[i]-s[q.front()];
                    l=q.front();
                    r=i;
                }
            }
            q.push_back(i);
        }
        ll res=0;
        res=s[l]+s[n]-s[r]+sum*c;
        return res>s[n]?res:s[n];
    }
     
    ll solve2()
    {
        deque<int> q;//存前缀和的最小值
        q.push_back(0);
        ll sum=0;
        int l,r;//最小值对应的连续子区间的左右端点
        l=0;
        r=0;
        for(int i=1;i<=n;i++)
        {
            while(q.empty()==0&&s[i]>=s[q.back()])
            {
                q.pop_back();
            }
            if(q.empty()==0)
            {
                if(sum>(s[i]-s[q.front()]))
                {
                    sum=s[i]-s[q.front()];
                    l=q.front();
                    r=i;
                }
            }
            q.push_back(i);
        }
        ll res=0;
        res=s[l]+s[n]-s[r]+sum*c;
        return res>s[n]?res:s[n];
    }
     
    int main()
    {
        std::ios::sync_with_stdio(false);
        cin.tie(0);
        cin>>n>>c;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            s[i]=s[i-1]+a[i];
        }
        a[0]=0;
        s[0]=0;
        ll ans1=solve1();
        ll ans2=solve2();
        ans=max(ans1,ans2);
        cout<<ans;
    }
    
    • 1

    Information

    ID
    2819
    Time
    1000ms
    Memory
    256MiB
    Difficulty
    10
    Tags
    # Submissions
    1
    Accepted
    1
    Uploaded By