题目
并查集中的 1..n表示上方, n+1..2n表示下方,合并时 2n+1..4n用于右侧的上下方并查集
#include<bits/stdc++.h>
using namespace std;
const int N=502;
#define mid (l+r>>1)
int mp[N<<2],a[N][N],n,m,x,y,i,j;
struct bing{
int f[N<<2];
void init(int n){for (int i=1;i<=n;i++) f[i]=i;}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
void merge(int x,int y){f[find(x)]=find(y);}
bool same(int x,int y){return find(x)==find(y);}
};
struct seg{
struct node{
int b,w;
bing U;
}t[N<<2];
void maintain(int rt,int l,int r){
t[rt].b=t[rt<<1].b+t[rt<<1|1].b;
t[rt].w=t[rt<<1].w+t[rt<<1|1].w;
t[rt].U.init(n<<2);
for (int i=1;i<=n<<1;i++){
t[rt].U.merge(i,t[rt<<1].U.find(i));
t[rt].U.merge(i+(n<<1),t[rt<<1|1].U.find(i)+(n<<1));
}
for (int i=1;i<=n;i++)
if (a[mid][i]==a[mid+1][i]){
if (t[rt].U.same(i+n,i+(n<<1))) continue;
t[rt].U.merge(i+n,i+(n<<1));
t[rt].w-=a[mid][i]==0;
t[rt].b-=a[mid][i]==1;
}
for (int i=1;i<=n<<2;i++) t[rt].U.find(i);
memset(mp,0,sizeof(mp));
for (int i=1;i<=n;i++)
if (!mp[t[rt].U.f[i]]) mp[t[rt].U.f[i]]=i,t[rt].U.f[i]=i;
else t[rt].U.f[i]=mp[t[rt].U.f[i]];
for (int i=n*3+1;i<=n<<2;i++){
if (!mp[t[rt].U.f[i]]) mp[t[rt].U.f[i]]=i-(n<<1),t[rt].U.f[i]=i-(n<<1);
else t[rt].U.f[i]=mp[t[rt].U.f[i]];
}
for (int i=1;i<=n;i++) t[rt].U.f[i+n]=t[rt].U.f[i+n*3];
for (int i=n<<1|1;i<=n<<2;i++) t[rt].U.f[i]=i;
}
void make(int rt,int l){
t[rt].U.init(n<<2);
t[rt].w=a[l][1]==0;
t[rt].b=a[l][1]==1;
t[rt].U.merge(1+n,1);
for (int i=2;i<=n;i++){
t[rt].U.merge(i+n,i);
if (a[l][i]==a[l][i-1]) t[rt].U.merge(i,i-1);
else t[rt].b+=a[l][i]==1,t[rt].w+=a[l][i]==0;
}
}
void build(int rt,int l,int r){
if (l==r){
make(rt,l);
return;
}
build(rt<<1,l,mid);
build(rt<<1|1,mid+1,r);
maintain(rt,l,r);
}
void change(int rt,int l,int r,int pos){
if (l==r){
make(rt,l);
return;
}
if (pos<=mid) change(rt<<1,l,mid,pos);
else change(rt<<1|1,mid+1,r,pos);
maintain(rt,l,r);
}
}T;
int main(){
scanf("%d",&n);
for (i=1;i<=n;i++)
for (j=1;j<=n;j++) scanf("%d",&a[i][j]);
T.build(1,1,n);
scanf("%d",&m);
while (m--){
scanf("%d%d",&x,&y);
a[x][y]^=1;
T.change(1,1,n,x);
printf("%d %d\n",T.t[1].b,T.t[1].w);
}
}