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 }