您的位置:首页 > 运维架构

【倒跑并查集维护连通块】NCPC 2016 A. Artwork

2017-10-26 13:35 477 查看
http://codeforces.com/gym/101550/attachments

【AC】

1 #include<bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const int maxn=1e3+2;
5 const int maxq=1e4+2;
6 int n,m,q;
7 struct node
8 {
9     int x1,y1;
10     int x2,y2;
11 }nd[maxq];
12 int fir[maxn][maxn];
13 bool vis[maxn][maxn];
14 int fa[maxn*maxn];
15 int id(int x,int y)
16 {
17     return (x-1)*m+y;
18 }
19
20 void init()
21 {
22     for(int i=1;i<=n*m;i++) fa[i]=i;
23 }
24
25 int getfa(int x)
26 {
27     return x==fa[x]?x:fa[x]=getfa(fa[x]);
28 }
29
30 void mix(int x,int y)
31 {
32     int fx=getfa(x);
33     int fy=getfa(y);
34     if(fx^fy)
35     {
36         fa[fx]=fy;
37     }
38 }
39 bool same(int x,int y)
40 {
41     return getfa(x)==getfa(y);
42 }
43 int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
44 bool inside(int x,int y)
45 {
46     return x>=1&&x<=n&&y>=1&&y<=m;
47 }
48 int ans[maxq];
49 int main()
50 {
51     while(~scanf("%d%d%d",&n,&m,&q))
52     {
53         memset(vis,false,sizeof(vis));
54         memset(fir,0,sizeof(fir));
55         init();
56         for(int i=1;i<=q;i++)
57         {
58             scanf("%d%d%d%d",&nd[i].x1,&nd[i].y1,&nd[i].x2,&nd[i].y2);
59             for(int j=nd[i].x1;j<=nd[i].x2;j++)
60             {
61                 for(int k=nd[i].y1;k<=nd[i].y2;k++)
62                 {
63                     vis[j][k]=true;
64                     if(!fir[j][k]) fir[j][k]=i;
65                 }
66             }
67         }
68         for(int i=1;i<=n;i++)
69         {
70             for(int j=1;j<=m;j++)
71             {
72                 if(!vis[i][j]&&inside(i+1,j)&&!vis[i+1][j]) mix(id(i,j),id(i+1,j));
73                 if(!vis[i][j]&&inside(i,j+1)&&!vis[i][j+1]) mix(id(i,j),id(i,j+1));
74             }
75         }
76         int cnt=0;
77         for(int i=1;i<=n;i++)
78         {
79             for(int j=1;j<=m;j++)
80             {
81                 if(!vis[i][j]&&getfa(id(i,j))==id(i,j)) cnt++;
82             }
83         }
84         for(int i=q;i>=1;i--)
85         {
86             ans[i]=cnt;
87             for(int x=nd[i].x1;x<=nd[i].x2;x++)
88             {
89                 for(int y=nd[i].y1;y<=nd[i].y2;y++)
90                 {
91                     if(fir[x][y]==i)
92                     {
93                         vis[x][y]=false;
94                         cnt++;
95                         for(int mv=0;mv<4;mv++)
96                         {
97                             int xx=x+dir[mv][0];
98                             int yy=y+dir[mv][1];
99                             if(!inside(xx,yy)) continue;
100                             if(vis[xx][yy]) continue;
101                             if(!same(id(x,y),id(xx,yy)))
102                             {
103                                 cnt--;
104                                 mix(id(x,y),id(xx,yy));
105                             }
106
107                         }
108                     }
109                 }
110             }
111         }
112         for(int i=1;i<=q;i++)
113         {
114             printf("%d\n",ans[i]);
115         }
116     }
117     return 0;
118 }


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: