Official

E - Grid Filling Editorial by en_translator


This problem can be solved in a total of \(O(HWN)\) time if you know:

  • \(\operatorname{count}[k][l][x]:=\) the number of squares \((i,j)\) such that \(k\lt i\leq H, l\lt j\leq W\) with numbers \(x\) written on them.

Indeed, when the squares from \((k+1,l+1)\) to \((k+h,l+w)\) are blacked out, there are

\[\operatorname{count}[0][0][x]-\operatorname{count}[k][l][x]+\operatorname{count}[k][l+w][x]-\operatorname{count}[k+h][l+w][x]+\operatorname{count}[k+h][l][x]\]

squares with \(x\) written on them that remain not blacked-out, so the answer for \((k,l)\) can be found in an \(O(N)\) time.

In order to find \(\operatorname{count}[k][l][x]\), it is sufficient to find the two-dimensional cumulative sums.

We describe the specific way.

We can let

  • \(\operatorname{count}[k][l][x]=\) \(1\) if \((k+1,j+1)\) has \(x\) written on it, and \(0\) otherwise

in a total of \(O(HWN)\) time. By iterating \((k,j,x)\) in a proper order while updating as \(\operatorname{count}[k][l][x]\leftarrow\operatorname{count}[k][l][x]+\operatorname{count}[k][l+1][x]\), we can let

  • \(\operatorname{count}[k][l][x]:=\) the number of squares \((k+1,l)\) such that \(k\lt l\leq W\) with \(x\) written on them.

Similarly, by updating as \(\operatorname{count}[k][l][x]\leftarrow\operatorname{count}[k][l][x]+\operatorname{count}[k+1][l][x]\), we can obtain the desired \(\operatorname{count}\).

Therefore, the problem has been solved in a total of \(O(HWN)\) time.

A sample code follows.

#include <iostream>
#include <vector>
#include <numeric>
#include <algorithm>

int main() {
    using namespace std;

    unsigned H, W, N, h, w;
    cin >> H >> W >> N >> h >> w;

    // count[i][j][x] = 1 if square (i + 1, j + 1) has x written on it, and 0 otherwise
    vector count(H, vector(W, vector<unsigned>(N)));

    for (auto &&row : count) {
        for (auto &&grid : row) {
            unsigned long A;
            cin >> A;
            ++grid[A - 1];
        }
        // sentinel
        row.emplace_back(N);
    }
    // sentinel
    count.emplace_back(W + 1, vector<unsigned>(N));

    // two-dimensional cumulative sums
    std::inclusive_scan(rbegin(count), rend(count), rbegin(count), [](auto &&i, auto &&j) {
        const auto vector_plus{[](auto &&i, auto &&j) {
            vector<unsigned> ret;
            transform(begin(i), end(i), begin(j), back_inserter(ret), plus<>{});
            return ret;
        }};
        std::inclusive_scan(rbegin(j), rend(j), rbegin(j), vector_plus);
        vector<vector<unsigned>> ret;
        transform(begin(i), end(i), begin(j), back_inserter(ret), vector_plus);
        return ret;
    });

    // board[i][j][x] = the number of squares below and in the left of square (i, j), with x written on them

    for (unsigned i{}; i + h <= H; ++i) {
        for (unsigned j{}; j + w <= W; ++j) {
            unsigned ans{};
            // increment the answer by 1 if there is one or more not-blacked-out squares with x written on them
            for (unsigned x{}; x < N; ++x)
                ans += count[0][0][x] + count[i + h][j][x] + count[i][j + w][x] !=
                       count[i][j][x] + count[i + h][j + w][x];
            cout << ans << " ";
        }
        cout << endl;
    }

    return 0;
}

posted:
last update: