区间连续和——考虑前缀和
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n,m;
int s[300090];
int q[300090];
int main() {
int x;
int ans=-0xfffffff;
scanf ("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf ("%d", &x);
s[i] = s[i - 1] + x;
}
for (int i = 1; i <= n; i++)
for (int j = i - m; j < i; j++)
ans = max (ans, s[i]-s[j]);
printf ("%d", ans);
return 0;
}
两层循环非吾愿 单调队列化二层循环
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n,m;
int s[300090];
int q[300090];
int num[300090];
int main() {
int x;
int head = 1, tail = 1;
int ans = -0xfffffff;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
scanf("%d", &x);
s[i] = s[i - 1] + x;
}
for (int i = 1; i <= n; i++) {
while(head<=tail&&num[head]<i-m) head++;
ans = max (ans, s[i] - q[head]);
while(q[tail] >= s[i]&&head <= tail) tail--;
q[++tail] = s[i];
num[tail] = i;
}
printf("%d", ans);
return 0;
}
此题与上题相似
上题m个里取1个 队列存前m个的最小值 +w[i]
此题连续取m个 队列存前m个的前缀和最小值 w[i]-..