题解 CF1197D 【Yet Another Subarray Problem】
这题的突破口在如何利用好
可以想到,我们如果单纯地用前缀和暴力枚举,复杂度是
那么我们想一下,如果
很明显,只要前面的
如果
为什么要这么分?因为我们需要进行分块,我们单独处理这两种情况。第一种情况下我们把分块的区间列出来
那么我们均摊一下,给每个块的值都整体减去
转移就是
因为对于
那么对于
代码:
#include <bits/stdc++.h>
using namespace std;
int n,k,m;
long long a[300005];
long long sum[300005];
long long r[300005];
long long ans;
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
for(int f=1;f<=m;f++)
{
long long maxn=0;
for(int i=f;i>=1;i--)
{
sum[1]+=a[i];
r[1]=max(sum[1],r[1]);
}
r[1]-=k;
sum[1]-=k;
for(int K=1;K<=(n-f)/m;K++)
{
for(int i=K*m+f;i>(K-1)*m+f;i--)
{
sum[K+1]+=a[i];
r[K+1]=max(sum[K+1],r[K+1]);
}
sum[K+1]-=k;
r[K+1]-=k;
}
for(int i=1;i<=(n-f)/m+1;i++)
{
maxn=max(maxn+sum[i],r[i]);
ans=max(maxn,ans);
sum[i]=0;
r[i]=0;
}
}
printf("%lld\n",ans);
}