用动态规划用fcur[i]表示以坐标i为右端点的区间最大和
f[i]表示前i个元素中的区间最大和,也就是特征值
转移方程见代码
然后求解过程也很简单
但是注意,简单加减会导致爆longlong,所以,如果确定f[1]不是最大值,那么就在过程中,对求出的最大值进行取模,以防爆longlong。
代码如下:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=1000005;
int n,p;
long long num[maxn];
long long f[maxn],fcur[maxn];
long long maxx(long long a,long long b){
return a<b?b:a;
}
int main(){
scanf("%d%d",&n,&p);
for(int i=1;i<=n;i++){
scanf("%lld",&num[i]);
fcur[i]=num[i];
}
for(int i=2;i<=n;i++){
fcur[i]=maxx(fcur[i],fcur[i-1]+num[i]);
}
f[1]=num[1];
for(int i=2;i<=n;i++){
f[i]=maxx(f[i-1],fcur[i]);
}
long long cur=f[1]*2;
int flag=1;
for(int i=2;i<=n;i++){
if(i==n){
if(flag){
printf("%lld",f[1]%p);
}else{
printf("%lld",cur%p);
}
return 0;
}
cur=maxx(cur,cur+f[i]);
if(flag&&cur>f[1]){
flag=0;
}
if(flag==0){
cur%=p;
}
}
return 0;
}