我们知道在最大值和最小值之外我们进行加减对答案是不影响的,而对于两个极值内部,我们一定会让他尽最大努力向一个方向走,因此我们可以把同一方向的放在一块。
但是我们不知道极值在哪里,只知道结构,所以我们循环整个取值去尝试找到最大值就好了,答案一定是其中之一的情况
/*input
3 100
1 2 -3
*/
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=3010;
int a[N],b;
int p[N];
ll mx(int n)
{
ll ans=0;
for(int i=0;i<b+1;i++)
{
ll l=0,r=0,idx=0,c=0;
for(int j=1;j<=n;j++)
{
if(a[j]) idx+=a[j];
else idx+=p[(c+i)%b],c++;
l=min(l,idx);
r=max(r,idx);
}
ans=max(ans,r-l+1);
}
return ans;
}
int main()
{
ll n,m;
ll sum=0;
cin>>n>>m;
for(int i=1;i<=n;i++) {
cin>>a[i]; sum+=a[i];
if(a[i]==0) b++;
}
if(abs(sum)>1ll*b*m)
cout<<-1<<endl;
else{
ll ans=0;
ll q=abs(sum);
for(int i=0;i<b;i++)
{
if(q+m<=(b-i-1)*m) p[i]=m,q+=m;
else if(q>0)
{
if(q%m==0) p[i]=-m,q-=m;
else p[i]=-q%m,q+=p[i];
}
if(sum<0) p[i]=-p[i];
}
ll test=sum;
for(int i=0;i<b;i++) test+=p[i];
if(test==0) ans=max(ans,mx(n));
for(int i=0;i<b;i++) p[i]=0;
q=abs(sum);
for(int i=0;i<b;i++)
{
if(m-q<=(b-i-1)*m) p[i]=-m,q-=m;
else if(q<0)
{
if(q%m==0) p[i]=m,q+=m;
else p[i]=-q%m,q+=p[i];
}
if(sum<0) p[i]=-p[i];
}
test=sum;
for(int i=0;i<b;i++) test+=p[i];
if(test==0) ans=max(ans,mx(n));
cout<<ans<<endl;
}
}