BZOJ1453 : [Wc]Dface双面棋盘
线段树套并查集,怎么暴力怎么写。
#include<cstdio>
#define N 202
struct P{int c[2],f[N*2];}T[N*4];
int n,m,i,j,a[N][N],f[N*4],t[N*4];
int F(int x){return f[x]==x?x:f[x]=F(f[x]);}
inline void cal(int x,int p){
int i,j=1;
T[x].c[a[p][1]]=1,T[x].c[a[p][1]^1]=0,T[x].f[1]=T[x].f[1+n]=1;
for(i=2;i<=n;i++){
if(a[p][i]!=a[p][j])T[x].c[a[p][j=i]]++;
T[x].f[i]=T[x].f[i+n]=j;
}
}
inline void up(int x,int p){
int l=x<<1,r=x<<1|1,i;
for(i=0;i<2;i++)T[x].c[i]=T[l].c[i]+T[r].c[i];
for(i=1;i<=n*2;i++)f[i]=T[l].f[i];
for(i=1;i<=n*2;i++)f[i+n*2]=T[r].f[i]+n*2;
for(i=1;i<=n;i++)if(a[p][i]==a[p+1][i]&&F(i+n)!=F(i+n*2))T[x].c[a[p][i]]--,f[f[i+n]]=f[i+n*2];
for(i=1;i<=n*4;i++){
f[i]=F(i);
if(i<=n)t[f[i]]=i;
if(i>n*3)t[f[i]]=i-n*2;
}
for(i=1;i<=n;i++)T[x].f[i]=t[f[i]];
for(i=1;i<=n;i++)T[x].f[i+n]=t[f[i+n*3]];
}
void build(int x,int a,int b){
if(a==b){cal(x,a);return;}
int mid=(a+b)>>1;
build(x<<1,a,mid),build(x<<1|1,mid+1,b),up(x,mid);
}
void change(int x,int a,int b,int c){
if(a==b){cal(x,a);return;}
int mid=(a+b)>>1;
if(c<=mid)change(x<<1,a,mid,c);else change(x<<1|1,mid+1,b,c);
up(x,mid);
}
int main(){
scanf("%d",&n);
for(i=1;i<=n;i++)for(j=1;j<=n;j++)scanf("%d",&a[i][j]);
build(1,1,n);
scanf("%d",&m);
while(m--)scanf("%d%d",&i,&j),a[i][j]^=1,change(1,1,n,i),printf("%d %d\n",T[1].c[1],T[1].c[0]);
return 0;
}

浙公网安备 33010602011771号