题解 P1714 【切蛋糕】
王将飞扬Cliffly · · 题解
思路楼下已经说的很清楚了,这里选择了单调队列优化,又快又好写。
维护一个前缀和sum[k]的单调递增队列 , 每次取出队首为最小值进行转移
#include<bits/stdc++.h>
#define rep(i,j,n) for(int i=j;i<=n;i++)
using namespace std;
const int N=5e5+10;
int n,m,sum[N],q[N],l=1,r,x,ans;
int main() {
scanf("%d%d",&n,&m);
rep(i,1,n) {
scanf("%d",&x) , sum[i]=sum[i-1]+x; //方便地使用前缀和数组
while(l<=r && sum[q[r]] > sum[i]) r--; //若不满足单调性就出队直到插入到合适的位置
q[++r]=i;
while(l<=r && q[l]<i-m) l++;
ans=max(ans,sum[i]-sum[q[l]]);
}
//似乎这里可能存在一些小问题?比如应使用sum[i-1]进行转移? 不过大体还是一样的
printf("%d",ans);
return 0;
}