A .Artwork

pro:给定N*M的白色格子,然后Q次黑棒,输出每次加黑棒后白色连通块的数量。(N,M<1e3, Q<1e4)

sol:倒着离线做,并查集即可。

(在线做法:https://www.cnblogs.com/asdfsag/p/10485607.html

#include<bits/stdc++.h>
#define ll long long
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn = 1e6 + 10;
int a[1010][1010], fa[maxn], ID[1010][1010];
struct node
{
    int x1, y1, x2, y2;
    node(){}
    node(int x1, int y1, int x2, int y2):x1(x1), y1(y1), x2(x2), y2(y2){}
}c[maxn];
int Find(int x){return x == fa[x] ? x : fa[x] = Find(fa[x]);}
int dir[][2] = {1,0,0,1,-1,0,0,-1};
stack<int>s;
int main()
{
    int n, m, q, tot = 0, x1, y1, x2, y2;
    scanf("%d%d%d", &n, &m, &q);
    for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++){ID[i][j] = ++tot; fa[tot] = tot;}
    for(int i = 1; i <= q; i++)
    {
        scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
        c[i] = node(x1, y1, x2, y2);
        for(int x = x1; x <= x2; x++)for(int y = y1; y <= y2; y++)a[x][y]++;
    }
    int white = 0, cnt = 0;
    for(int i = 1; i <= n; i++)for(int j = 1; j <= m; j++)if(!a[i][j])
    {
        white++;
        for(int k = 0; k < 4; k++)
        {
            int x = i + dir[k][0], y = j + dir[k][1];
            if(x >= 1 && x <= n && y >= 1 && y <= m && !a[x][y])
            {
                int u = ID[i][j], v = ID[x][y];
                u = Find(u);v = Find(v);
                if(u != v)fa[u] = v, cnt++;
            }
        }
    }
    s.push(white - cnt);
    for(int i = q; i >= 2; i--)
    {
        for(int x = c[i].x1; x <= c[i].x2; x++)
            for(int y = c[i].y1; y <= c[i].y2; y++)
        {
            a[x][y]--;
            if(!a[x][y])
            {
                white++;
                for(int k = 0; k < 4; k++)
                {
                    int xx = x + dir[k][0], yy = y + dir[k][1];
                    if(xx >= 1 && xx <= n && yy >= 1 && yy <= m && !a[xx][yy])
                    {
                        int u = ID[x][y], v = ID[xx][yy];
                        u = Find(u);v = Find(v);
                        if(u != v)fa[u] = v, cnt++;
                    }
                }
            }
        }
        s.push(white - cnt);
    }
    while(!s.empty()){cout<<s.top()<<endl;s.pop();}
    return 0;
}
View Code

相关文章:

  • 2022-12-23
  • 2021-05-31
  • 2021-10-15
  • 2022-12-23
  • 2021-11-11
  • 2022-12-23
  • 2021-09-07
  • 2021-07-26
猜你喜欢
  • 2021-09-02
  • 2021-10-01
  • 2022-02-25
  • 2021-11-29
  • 2022-12-23
  • 2021-10-17
  • 2022-12-23
相关资源
相似解决方案