这是一道好题,按行建线段树,每个点维护上下边界的连通性,详细见代码注释

网上写法不一,自认为比较简单,就放出来相出来献丑吧

  1 var u,d:array[0..810,0..205] of longint;  //u[]上边界,d[]下边界
  2     s,fa,q:array[0..810] of longint;
  3     c:array[0..810,0..1] of longint;  //维护对应颜色块数
  4     a:array[0..205,0..205] of longint;
  5     j,i,n,m,x,y:longint;
  6 
  7 function getf(x:longint):longint;
  8   begin
  9     if fa[x]<>x then fa[x]:=getf(fa[x]);
 10     exit(fa[x]);
 11   end;
 12 
 13 procedure union(i,m:longint);
 14   var j,k1,k2,t:longint;
 15   begin
 16     c[i,0]:=c[i*2,0]+c[i*2+1,0];
 17     c[i,1]:=c[i*2,1]+c[i*2+1,1];
 18     for j:=1 to n do
 19     begin
 20       fa[j]:=u[i*2,j];
 21       fa[j+n]:=d[i*2,j];
 22       fa[j+2*n]:=u[i*2+1,j]+2*n;  //防止编号重复
 23       fa[j+3*n]:=d[i*2+1,j]+2*n;
 24     end;
 25     for j:=1 to n do
 26       if a[m+1,j]=a[m,j] then  //子区间相邻连通块合并
 27       begin
 28         k1:=getf(fa[j+n]);
 29         k2:=getf(fa[j+2*n]);
 30         if k1<>k2 then
 31         begin
 32           fa[k2]:=k1;
 33           dec(c[i,a[m,j]]);
 34         end;
 35       end;
 36     t:=0;
 37     for j:=1 to n do
 38     begin
 39       k1:=getf(fa[j]); //对整个区间上边界连通性重新标号
 40       if s[k1]=0 then
 41       begin
 42         inc(t);
 43         q[t]:=k1;
 44         s[k1]:=j;  
 45       end;
 46       u[i,j]:=s[k1];
 47       k2:=getf(fa[j+3*n]); //对整个区间下边界连通性重新标号
 48       if s[k2]=0 then
 49       begin
 50         inc(t);
 51         q[t]:=k2;
 52         s[k2]:=j+n;  //防止编号重复,上边界编号1~n,下边界编号n+1~2n
 53       end;
 54       d[i,j]:=s[k2];
 55     end;
 56     for j:=1 to t do
 57       s[q[j]]:=0;
 58   end;
 59 
 60 procedure leaf(i,row:longint);
 61   var j,t:longint;
 62   begin
 63     t:=0;
 64     c[i,0]:=0; c[i,1]:=0;
 65     for j:=1 to n do
 66       if (j<>1) and (a[row,j]=a[row,j-1]) then
 67       begin
 68         u[i,j]:=u[i,j-1];
 69         d[i,j]:=d[i,j-1];
 70       end
 71       else begin
 72         inc(c[i,a[row,j]]);
 73         u[i,j]:=j; d[i,j]:=j; //连通块以起始位置为编号,这样比较方便
 74       end;
 75   end;
 76 
 77 procedure build(i,l,r:longint);
 78   var m:longint;
 79   begin
 80     if l=r then leaf(i,l)
 81     else begin
 82       m:=(l+r) shr 1;
 83       build(i*2,l,m);
 84       build(i*2+1,m+1,r);
 85       union(i,m);
 86     end;
 87   end;
 88 
 89 procedure work(i,l,r:longint);
 90   var m:longint;
 91   begin
 92     if l=r then leaf(i,l)
 93     else begin
 94       m:=(l+r) shr 1;
 95       if x<=m then work(i*2,l,m)
 96       else work(i*2+1,m+1,r);
 97       union(i,m);
 98     end;
 99   end;
100 
101 begin
102   readln(n);
103   for i:=1 to n do
104     for j:=1 to n do
105       read(a[i,j]);
106   build(1,1,n);
107   readln(m);
108   for i:=1 to m do
109   begin
110     readln(x,y);
111     a[x,y]:=1-a[x,y];
112     work(1,1,n);
113     writeln(c[1,1],' ',c[1,0]);
114   end;
115 end.
View Code

 

posted on 2015-05-09 16:58  acphile  阅读(208)  评论(0编辑  收藏  举报