题意

给出一个长度为\(n\)的数列和数字\(x\),经过最多一次操作将数列的一个子段的每个元素变为\(a[i]*x\),使该数列的最大子段和最大

分析

将这个数列分为3段考虑,第一段和第三段是未修改的,第二段是修改的子段

\(dp[i][j]\)为第\(i\)个数字为第\(j+1\)段的最大子段和

三种转移方程

  • 第一段:\(dp[i][0]=max(a[i],dp[i-1][0]+a[i])\)
  • 第二段:\(dp[i][1]=max(a[i]*x,dp[i-1][0]+a[i]*x,dp[i-1][1]+a[i]*x)\)
  • 第三段:\(dp[i][2]=max(a[i],dp[i-1][0]+a[i],dp[i-1][1]+a[i],dp[i-1][2]+a[i])\)

Code

    #include<bits/stdc++.h>
    #define fi first
    #define se second
    using namespace std;
    typedef long long ll;
    const double PI=acos(-1.0);
    const double eps=1e-6;
    const ll inf=1e18;
    const ll mod=1e9+7;
    const int maxn=3e5+10;
    int n;
    ll x;
    ll a[maxn];
    ll dp[maxn][3];
    int main(){
        ios::sync_with_stdio(false);
        cin>>n>>x;
        ll ans=0;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            dp[i][0]=max(a[i],dp[i-1][0]+a[i]);
            dp[i][1]=max({a[i]*x,dp[i-1][1]+a[i]*x,dp[i-1][0]+a[i]*x});
            dp[i][2]=max({a[i],dp[i-1][0]+a[i],dp[i-1][1]+a[i],dp[i-1][2]+a[i]});
            ans=max({ans,dp[i][2],dp[i][0],dp[i][1]});
        }
        cout<<ans<<endl;
        return 0;
    }