Comet OJ - Contest #13-C2
C2- Royal Buddha stone bowl - not broken the will - "(difficult version)
It is a disjoint-set. Title recently done disjoint-set of seemingly find many.
Thinking
Consider first, into each treatment rectangular considering only from the point 0 1. We complexity of controls in the \ (O (nm) \) .
So, we consider how to maintain a position at each point of 0. Because we know disjoint-set is used to maintain the same relationship of some elements . Therefore, we consider each point \ (fa \) is a zero position at the line. So, when we put a point of 0 1 dyed, the point of this point and the left merge. We can guarantee this current point \ (fa \) is the next position 0, while ensuring their own "son" of \ (fa \) into a new location next to zero.
So consider how dynamic maintenance Unicom block.
To open a set of maintenance and check of a link block. We let all gave answers 1 plus 1. When two blocks 1 Unicom combined answer subtract 1.
Unicom do not control sequence, each time a process 1, can be regarded surrounding combined merged. (This is disjoint-set another important character. When you put every relationship can get back are combined, finally able to get all the relationship).
Complexity \ (O (nm \ Alpha (nm) + NQ) \) . (Plus merger by rank)
Code
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=1005;
int map[maxn][maxn],fa1[maxn][maxn],fa2[maxn*maxn],id[maxn][maxn],n,m,q,tot,ans;
char s[maxn];
int get1(int x,int y) {return (fa1[x][y]==y)?y:fa1[x][y]=get1(x,fa1[x][y]);}
void uni1(int x,int u,int v){fa1[x][get1(x,u)]=get1(x,v);}
int get2(int x){return (fa2[x]==x)?x:fa2[x]=get2(fa2[x]);}
void uni2(int u,int v){fa2[get2(u)]=get2(v);}
int dx[5]={0,1,-1,0,0};
int dy[5]={0,0,0,1,-1};
void mark(int x,int y) {//color (x,y)
id[x][y]=++tot;ans++;fa2[tot]=tot;
if(get1(x,y)!=get1(x,y+1))uni1(x,y,y+1);
for(int i=1;i<=4;i++) {
int nx=x+dx[i],ny=y+dy[i];
if(1<=nx<=n&&1<=ny<=m&&id[nx][ny]) {
if(get2(id[nx][ny])!=get2(id[x][y])){uni2(id[nx][ny],id[x][y]);ans--;}
}
}
}
int main() {
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) {
scanf("%s",s+1);
for(int j=1;j<=m;j++)map[i][j]=(s[j]=='1')?1:0;
}
for(int i=1;i<=n;i++)for(int j=1;j<=m+1;j++)fa1[i][j]=j;
for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(map[i][j])mark(i,j);
scanf("%d",&q);
for(int t=1;t<=q;t++) {
int d[5];scanf("%d%d%d%d",&d[1],&d[3],&d[2],&d[4]);//x1 x2 y1 y2
for(int i=d[1];i<=d[2];i++) {
for(int j=get1(i,d[3]);j<=d[4];j=get1(i,j)) {
mark(i,j);
}
}
printf("%d\n",ans);
}
return 0;
}