首先考虑暴力做法,可以先求一遍前缀和 sum,然后ans = max(ans, sum[i] - sum[k]) (i - q <= k <= i - p)
但这个肯定会超时。
仔细看这个公式,sum[i] 不变,只用求最小 sum[k] 就行,所以可以用单调队列维护这个区间的最小 sum[k]。
——代码
1 #include <cstdio> 2 #include <iostream> 3 #define LL long long 4 5 using namespace std; 6 7 const int MAXN = 100010; 8 int n, p, q, h = 1, t; 9 LL a[MAXN], que[MAXN], ans = -0x7fffffff; 10 11 int main() 12 { 13 int i, j; 14 scanf("%d %d %d", &n, &p, &q); 15 for(i = 1; i <= n; i++) 16 { 17 scanf("%lld", &a[i]); 18 a[i] += a[i - 1]; 19 } 20 for(i = p; i <= n; i++) 21 { 22 while(h <= t && a[que[t]] > a[i - p]) t--; 23 que[++t] = i - p; 24 while(h <= t && que[h] < i - q) h++; 25 ans = max(ans, a[i] - a[que[h]]); 26 } 27 printf("%lld", ans); 28 return 0; 29 }