Educational Codeforces Round 69 (Rated for Div. 2) D. Yet Another Subarray Problem 【数学+分块】

一、题目

  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 }

猜你喜欢

转载自www.cnblogs.com/dybala21/p/11328463.html