目录

CF1304F2-Animal Observation (hard version)

CF1304F2-Animal Observation (hard version)

题目:

题目描述:

The only difference between easy and hard versions is the constraint on $ k $ .

Gildong loves observing animals, so he bought two cameras to take videos of wild animals in a forest. The color of one camera is red, and the other one’s color is blue.

Gildong is going to take videos for $ n $ days, starting from day $ 1 $ to day $ n $ . The forest can be divided into $ m $ areas, numbered from $ 1 $ to $ m $ . He’ll use the cameras in the following way:

  • On every odd day ( $ 1 $ -st, $ 3 $ -rd, $ 5 $ -th, …), bring the red camera to the forest and record a video for $ 2 $ days.
  • On every even day ( $ 2 $ -nd, $ 4 $ -th, $ 6 $ -th, …), bring the blue camera to the forest and record a video for $ 2 $ days.
  • If he starts recording on the $ n $ -th day with one of the cameras, the camera records for only one day.

Each camera can observe $ k $ consecutive areas of the forest. For example, if $ m=5 $ and $ k=3 $ , he can put a camera to observe one of these three ranges of areas for two days: $ [1,3] $ , $ [2,4] $ , and $ [3,5] $ .

Gildong got information about how many animals will be seen in each area on each day. Since he would like to observe as many animals as possible, he wants you to find the best way to place the two cameras for $ n $ days. Note that if the two cameras are observing the same area on the same day, the animals observed in that area are counted only once.

输入格式:

The first line contains three integers $ n $ , $ m $ , and $ k $ ( $ 1 \le n \le 50 $ , $ 1 \le m \le 2 \cdot 10^4 $ , $ 1 \le k \le m $ ) – the number of days Gildong is going to record, the number of areas of the forest, and the range of the cameras, respectively.

Next $ n $ lines contain $ m $ integers each. The $ j $ -th integer in the $ i+1 $ -st line is the number of animals that can be seen on the $ i $ -th day in the $ j $ -th area. Each number of animals is between $ 0 $ and $ 1000 $ , inclusive.

输出格式:

Print one integer – the maximum number of animals that can be observed.

样例:

样例输入 1:

1
2
3
4
5
4 5 2
0 2 1 1 0
0 0 3 1 2
1 0 4 3 1
3 3 0 0 4

样例输出 1:

1
25

样例输入 2:

1
2
3
4
3 3 1
1 2 3
4 5 6
7 8 9

样例输出 2:

1
31

样例输入 3:

1
2
3
4
3 3 2
1 2 3
4 5 6
7 8 9

样例输出 3:

1
44

样例输入 4:

1
2
3
4
3 3 3
1 2 3
4 5 6
7 8 9

样例输出 4:

1
45

思路:

实现:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include "ybwhead/ios.h"
#define ll long long
#define lc x << 1
#define rc x << 1 | 1
#define mid ((l + r) >> 1)
using namespace std;
struct Tree //线段树
{
    ll maxv[80005];
    void pushup(int x)
    {
        maxv[x] = max(maxv[lc], maxv[rc]);
    }
    void update(int x, int l, int r, int p, ll v)
    {
        if (l == r)
        {
            maxv[x] = v;
            return;
        }
        if (p <= mid)
            update(lc, l, mid, p, v);
        else
            update(rc, mid + 1, r, p, v);
        pushup(x);
    }
    ll ask(int x, int l, int r, int from, int to)
    {
        if (from > to)
            return -1e12;
        if (l >= from && r <= to)
            return maxv[x];
        ll ans = -1e12;
        if (from <= mid)
            ans = max(ans, ask(lc, l, mid, from, to));
        if (to > mid)
            ans = max(ans, ask(rc, mid + 1, r, from, to));
        return ans;
    }
};
Tree t1, t2, t3; //t1,t2,t3分别维护f,x,y
int n, m, l;
ll a[55][20005], s[55][20005], f[20005];
int main()
{
    yin >> n >> m >> l;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            yin >> a[i][j];
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            s[i][j] = s[i][j - 1] + a[i][j];
    for (int i = 1; i <= 80000; i++)
        t1.maxv[i] = t2.maxv[i] = t3.maxv[i] = -1e12;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j + l - 1 <= m; j++)
        {
            f[j] = max(t1.ask(1, 1, m, 1, j - l), t1.ask(1, 1, m, j + l, m));
            f[j] = max(f[j], t2.ask(1, 1, m, j - l + 1, j) + s[i][j - 1]);
            f[j] = max(f[j], t3.ask(1, 1, m, j + 1, j + l) - s[i][j + l - 1]);
            f[j] = max(f[j], 0ll);
        }
        for (int j = 1; j + l - 1 <= m; j++)
        {
            f[j] = f[j] + s[i][j + l - 1] - s[i][j - 1] + s[i + 1][j + l - 1] - s[i + 1][j - 1];
            t1.update(1, 1, m, j, f[j]);
            t2.update(1, 1, m, j, f[j] - s[i + 1][j + l - 1]);
            t3.update(1, 1, m, j, f[j] + s[i + 1][j - 1]);
        }
    }
    yout << t1.ask(1, 1, n, 1, n) << endl;
    return 0;
}