1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| #include<bits/stdc++.h> using namespace std;
#define rep(i,j,k) for(int i=(j);i<=(k);i++) struct DSU{ int f[810]; inline void ini(int n){rep(i,1,n)f[i]=i;} inline int find(int x){return x==f[x]?x:f[x]=find(f[x]);} inline void join(int x,int y){f[find(x)]=find(y);} };
int mp[222][222];
#define ml ((l+r)>>1) #define mr (ml+1) int ls[210*2],rs[210*2],tot,n; struct treenode{ DSU d; int sz[2]; }tr[210*2];
void build(treenode&res,int*a){ res.d.ini(n+n); rep(i,2,n) if(a[i]==a[i-1]) res.d.join(i,i-1),res.d.join(n+i,n+i-1); rep(i,1,n) res.d.join(i+n,i); res.sz[0]=res.sz[1]=0; static int vis[220]; rep(i,1,n) vis[i]=0; rep(i,1,n) if(!vis[res.d.find(i)]) res.sz[a[i]]++,vis[res.d.find(i)]=1; }
void merge(treenode&a,treenode&b,int c1,int c2){ a.sz[0]=a.sz[0]+b.sz[0]; a.sz[1]=a.sz[1]+b.sz[1]; rep(i,1,2*n) a.d.f[i+2*n]=b.d.f[i]+2*n; DSU&dsu=a.d; rep(i,1,n) if(mp[c1][i]==mp[c2][i]){ if(dsu.find(i+n)!=dsu.find(i+2*n)){ dsu.join(i+n,i+2*n); a.sz[mp[c1][i]]--; } } rep(i,1,n) if(dsu.find(i)>n&&dsu.find(i)<=3*n) dsu.f[dsu.find(i)]=i,dsu.f[i]=i; rep(i,3*n+1,4*n) if(dsu.find(i)>n&&dsu.find(i)<=3*n) dsu.f[dsu.find(i)]=i,dsu.f[i]=i; rep(i,3*n+1,4*n) dsu.f[i-2*n]=dsu.f[i]>n?dsu.f[i]-2*n:dsu.f[i]; }
void build(int&u,int l,int r){ u=++tot; if(l==r){ build(tr[u],mp[l]); return; } build(ls[u],l,ml); build(rs[u],mr,r); tr[u]=tr[ls[u]]; merge(tr[u],tr[rs[u]],ml,mr); }
void update(int&u,int l,int r,int q){ if(l==r){ build(tr[u],mp[l]); return; } if(q<=ml) update(ls[u],l,ml,q); else update(rs[u],mr,r,q); tr[u]=tr[ls[u]]; merge(tr[u],tr[rs[u]],ml,mr); }
int main(){ scanf("%d",&n); rep(i,1,n)rep(j,1,n) scanf("%d",&mp[i][j]); int rt; build(rt,1,n); int m;scanf("%d",&m); while(m--){ int x,y;scanf("%d%d",&x,&y); mp[x][y]^=1; update(rt,1,n,x); printf("%d %d\n",tr[1].sz[1],tr[1].sz[0]); } }
|