CSU2020:Artwork (and check the collection)

Topic link: http://acm.csu.edu.cn/csuoj/problemset/problem?pid=2022

题目:
Description
A template for an artwork is a white grid of n × m squares. The artwork will be created by painting q horizontal and vertical black strokes. A stroke starts from square (x1, y1), ends at square (x2,y2)(x1=x2 or y1=y2) and changes the color of all squares (x, y) to black where x1 ≤ x ≤ x2 and y1 ≤ y ≤ y2. The beauty of an artwork is the number of regions in the grid. Each region consists of one or more white squares that are connected to each other using a path of white squares in the grid, walking horizontally or vertically but not diagonally. The initial beauty of the artwork is 1. Your task is to calculate the beauty after each new stroke. Figure A.1 illustrates how the beauty of the artwork varies in Sample Input 1.

write picture description here

Input
The first line of input contains three integers n, m and q (1 ≤ n, m ≤ 1000, 1 ≤ q ≤ 104). Then follow q lines that describe the strokes. Each line consists of four integersx1,y1,x2 and y2(1 ≤ x1 ≤ x2 ≤ n, 1 ≤ y1 ≤ y2 ≤ m). Either x1 = x2 or y1=y2(or both).

Output
For each of the q strokes, output a line containing the beauty of the artwork after the stroke.

Sample Input
4 6 5
2 2 2 6
1 3 4 3
2 5 3 5
4 6 4 6
1 6 4 6
Sample Output
1
3
3
4
3
Hint
Source
NCPC 2016

The meaning of the question: first give you a graph of size n*m, there are several queries, each query will input two points on a straight line (can be the same point), the point between the two points and the It will be dyed itself, and then find the number of connected areas that are not dyed, and the dyed points in the front will still exist in other queries.

Idea: first store all the queries, and color all the points to be colored in all queries, and then reverse traversal from the last query to make the colored points in the query uncolored, and color the connected area at this time. save. It is convenient to deal with connected regions using union search. Because the coordinates x and y of this graph are opposite, it is very uncomfortable, so I marked all the grids from the upper left to the lower right starting from number 1 until n*m.

Code:

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>

using namespace std;

const int maxn =10000+5;
const int maxn1 =1000000+5;
int vis[maxn1];//标记数组
int fa[maxn1],son[maxn1];
int n,m,q,cnt,ans;

int find_(int x)
{
    return x==fa[x]? x: x=find_(fa[x]);
}

struct query//几次查询染色
{
    int x,y,x1,y1,sum;//染色的起点坐标和终点坐标、答案。

} Q[maxn];


void solve(int a,int b)
{
    int x,y;
    x=find_(a);
    y=find_(b);
    if(x==y)
        return;
    ans--;
    if(son[x]>son[y])
    {
        fa[y]=x;
        son[x]+=son[y];
    }
    else
    {
        fa[x]=y;
        son[y]+=son[x];
    }
}

void union_(int i)
{
    ans++;
    son[i]=1;
    if(i+1<=n*m&&vis[i+1]==0)
    {

        if(i%n!=0)
            solve(i,i+1);
    }
    if(i-1>=1&&vis[i-1]==0)
    {

        if(i%n!=1)
            solve(i-1,i);
    }
    if(i+n<=n*m&&vis[i+n]==0)
    {


        solve(i,i+n);
    }
    if(i-n>=1&&vis[i-n]==0)
    {


        solve(i-n,i);
    }
    return;
}

int main()
{
    // freopen("in.txt","r",stdin);
    while(scanf("%d%d%d",&n,&m,&q)!=EOF)
    {
        memset(son,0,sizeof(son));
        cnt=0;
        ans=0;
        for(int i=1; i<=n*m; i++)
        {
            vis[i]=0;
            fa[i]=i;
        }
        for(int i=1; i<=q; i++)
        {
            scanf("%d%d%d%d",&Q[i].x,&Q[i].y,&Q[i].x1,&Q[i].y1);
            Q[i].sum=0;
            if(Q[i].x==Q[i].x1)
            {
                for(int j=(Q[i].y-1)*n+Q[i].x; j<=(Q[i].y1-1)*n+Q[i].x1; j+=n)
                    vis[j]++;//一个格子可以多次被染色,所以我标记一下,当vis==0时,证明没有被染色了。
            }
            else if(Q[i].y==Q[i].y1)
            {
                for(int j=(Q[i].y-1)*n+Q[i].x; j<=(Q[i].y1-1)*n+Q[i].x1; j++)
                    vis[j]++;
            }

        }

        for(int i=1; i<=n*m; i++)
        {
            if(vis[i]==0)
                union_(i);
        }
        Q[q].sum=ans;
        for(int i=q; i>=2; i--)
        {

            if(Q[i].x==Q[i].x1)
            {
                for(int j=(Q[i].y-1)*n+Q[i].x; j<=(Q[i].y1-1)*n+Q[i].x1; j+=n)
                    vis[j]--;
                for(int j=(Q[i].y-1)*n+Q[i].x; j<=(Q[i].y1-1)*n+Q[i].x1; j+=n)
                {
                    if(vis[j]==0)
                        union_(j);
                }

            }
            else if(Q[i].y==Q[i].y1)
            {
                for(int j=(Q[i].y-1)*n+Q[i].x; j<=(Q[i].y1-1)*n+Q[i].x1; j++)
                    vis[j]--;
                for(int j=(Q[i].y-1)*n+Q[i].x; j<=(Q[i].y1-1)*n+Q[i].x1; j++)
                {
                    if(vis[j]==0)
                        union_(j);
                }

            }
            cnt++;
            Q[q-cnt].sum=ans;
        }
        for(int i=q-cnt; i<=q; i++)
            printf("%d\n",Q[i].sum);
    }
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326008668&siteId=291194637