一、题目
D. Yet Another Subarray Problem
二、分析
公式的推导时参考的洛谷聚聚们的推导
重点是公式的推导,推导出公式后,分块是很容易想的。但是很容易写炸。
1 有些地方容易溢出,这和设置的无穷大的值的大小也有关。
2 如果每次确定了边界$r$,那么在枚举$m$的余数的情况时,一定注意到比$r$大的还不能枚举。
三、AC代码
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 #define Min(a, b) ((a)<(b)?(a):(b)) 5 #define Max(a, b) ((a)>(b)?(a):(b)) 6 typedef long long ll; 7 const int maxn = 3e5 + 13; 8 const ll inf = 1e15 ; 9 int n, m; 10 ll k; 11 int a[maxn]; 12 ll sum[maxn]; 13 ll D[maxn]; 14 ll Dmin[15]; 15 16 int main() 17 { 18 //freopen("input.txt", "r", stdin); 19 while(scanf("%d %d %I64d", &n, &m, &k) != EOF) 20 { 21 fill(Dmin, Dmin + 11, inf); 22 sum[0] = 0; 23 for(int i = 1; i <= n; i++) 24 { 25 scanf("%d", &a[i]); 26 sum[i] = sum[i - 1] + a[i]; 27 D[i] = sum[i] - k * (i / m); 28 } 29 ll ans = 0; 30 Dmin[0] = 0; 31 for(int i = 1; i <= n; i++) 32 { 33 ll res = -inf; 34 for(int j = 0; j < m; j++) 35 { 36 int f = ceil(1.0 * ( (i % m) - j) / m); 37 res = Max(res, D[i] - Dmin[j] - k * f); 38 } 39 Dmin[i % m] = Min(D[i], Dmin[i % m]); 40 ans = Max(res, ans); 41 } 42 printf("%lld\n", ans); 43 } 44 45 46 }
来源:https://www.cnblogs.com/dybala21/p/11328463.html