hls J 了我一手,我还是写错,菜枯.jpg ,眼看小号就要追上大号了,突然2场掉了120分。。。
x是正数的话,我们直接就求最大子区间和乘以x,x<=0的话,可以知道我们如果选择[j,i]乘以x,那么最大值就是[j,i]*x+i右边能拓展出的最大区间和+j左边能拓展出的最大区间和,
我们设f1mx[j]表示以j结尾的能向左拓展出的最大区间和,f2mx[i]表示以i开头能向右拓展出的最大区间和
那么枚举i,ans=max(f1mx[j]+f2mx[i+1]+x*(sum[i]-sum[j]))
将这个式子拆开,那么每次维护tmp=max(f1mx[j]-x*sum[j]) ,ans=max(tmp+f2mx[i+1]+x*sum[i])。
写错的原因是f1mx[j] 和 f2mx[j]没有与0比较,假如某个位置向右必定是负贡献的,那么还不如不向右拓展,即为0.
#include<bits/stdc++.h>
#define maxl 300010
using namespace std;
int n;
long long x,ans;
long long a[maxl],num[maxl],sum[maxl];
long long f1mx[maxl],f2mx[maxl],f[maxl];
long long q[maxl],d[2];
char s[maxl];
inline void prework()
{
scanf("%d%lld",&n,&x);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]),sum[i]=sum[i-1]+a[i];
}
inline void mainwork()
{
long long mini=0,mx,l,r,tmp;
mini=0;
for(int i=1;i<=n;i++)
{
f1mx[i]=max(sum[i]-mini,0ll);
mini=min(mini,sum[i]);
}
mx=sum[n];
for(int i=n;i>=1;i--)
{
f2mx[i]=max(mx-sum[i-1],0ll);
mx=max(mx,sum[i-1]);
}
l=1;r=0;mx=0;ans=0;
for(int i=1;i<=n;i++)
{
tmp=f1mx[i]-sum[i]*x;
mx=max(mx,tmp);
f[i]=x*sum[i]+f2mx[i+1]+mx;
ans=max(f[i],ans);
}
}
inline void print()
{
printf("%lld",ans);
}
int main()
{
prework();
mainwork();
print();
return 0;
}