嘘~ 正在从服务器偷取页面 . . .

[ABC045D] Snuke's Coloring 题解


[ABC045D] Snuke's Coloring 题解

题目链接:[ABC045D] Snuke's Coloring

题意

给定一个 \(H\)\(W\) 列的矩形,再给定矩形上 \(N\) 个黑格子的坐标。

对于每个 \(0\le i\le9\) ,求出有多少个 \(3\times3\) 的子矩阵包含有恰好 \(i\) 个黑格子。

\(3 \leq H \leq 10^9, ~3 \leq W \leq 10^9,~0 \leq N \leq \min \left(10^5, H \times W\right)\)

\(f_{i,j}\) 表示点 \((i,j)\) 到点 \((i + 2, j + 2)\) 的矩阵的答案。

由于 \(H,W\) 都很大,但 \(N\) 很小,而每个黑点至多对周围的 \(8\) 个格子产生贡献

那么我们只需要把所有涉及贡献的 \(f\) 计算一下,显然其他的都是 \(0\) ,并且可以 \(\mathcal{O}(1)\) 计算。

时间复杂度 \(\mathcal{O}(n \log n)\)

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
typedef pair<int,int> pii;
void up(int &x,int y) { x < y ? x = y : 0; }
void down(int &x,int y) { x > y ? x = y : 0; }
#define N ((int)(1e5 + 15))

int H,W,n,ans[N]; map<pii,int> mp;
signed main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    // freopen("check.in","r",stdin);
    // freopen("check.out","w",stdout);
    cin >> H >> W >> n;
    for(int i = 1, x, y; i <= n; i++)
    {
        cin >> x >> y;
        for(int tx = x - 2; tx <= x; tx++)
            for(int ty = y - 2; ty <= y; ty++)
                if(tx > 0 && tx < H - 1 && ty > 0 && ty < W - 1) ++mp[{tx, ty}];
    }
    for(auto && i : mp) ++ans[i.second];
    ans[0] += (H - 2) * (W - 2) - mp.size();
    for(int i = 0; i <= 9; i++) cout << ans[i] << '\n';
    return 0;
}

文章作者: q779
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 q779 !
评论
  目录