P1714 切蛋糕(前缀和&单调队列)
思路:单调队列+前缀和,枚举每个区间右端点,然后利用单调队列找到在范围内的最小左端点,不断更新答案即可。
时间复杂度:
AC代码:
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
int pre[N],n,m,ans=-2e9;
deque<int>q;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&pre[i]),pre[i]+=pre[i-1];
q.push_back(0);//考虑区间左端为1的情况.
for(int i=1;i<=n;i++){
while(q.size()&&pre[q.back()]>pre[i]) q.pop_back();//保证队首到队尾是单调递增的
q.push_back(i);
while(q.front()<i-m) q.pop_front();//越界就pop队首
if(ans<pre[i]-pre[q.front()]) ans=pre[i]-pre[q.front()];//更新最大值
}
printf("%d\n",ans);
return 0;
}