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

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

 

posted @ 2017-10-26 13:35  shulin15  阅读(426)  评论(0编辑  收藏  举报