P1714 切蛋糕

原题链接

前缀和+单调队列

这题维护的不是[i-k+1,i]的区间,而是[i-k,i-1]的区间,因为我们要求前缀和的最大值,这道题如果让单调队列维护递减的序列,而边界点不好确定(因为我们不知道区间多大),这样就不利于求前缀和,可以转化一下,让单调队列维护区间最小值,用当前的前缀和sum[i]减去区间维护的最小值,所以hh在小于i-k才++,这里的滑动区间是跟在i后面的,因为不能取0块

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 5e5+10;
 4 int q[N],a[N],sum[N],n,k;//区间最大k
 5 int main()
 6 {
 7     scanf("%d%d",&n,&k);
 8     int hh = 0,tt = -1,maxn = 1<<31;
 9     for(int i=1;i<=n;i++){
10         scanf("%d",&a[i]);
11         sum[i] = sum[i-1]+a[i];
12     }
13     for(int i=1;i<=n;i++){
14         while(hh<=tt&&q[hh]<i-k) ++hh;//求的是最大前缀和,滑动窗口的大小是k+1,求
15         maxn = max(maxn,sum[i]-sum[q[hh]]);
16         while(hh<=tt&&sum[q[tt]]>=sum[i]) --tt;
17         q[++tt] = i;
18     }
19     printf("%d\n",maxn);
20     return 0;
21 }

 

posted @ 2020-12-27 19:07  acmloser  阅读(122)  评论(0编辑  收藏  举报