bzoj 1453 双面棋盘
题目大意:
一个黑白方格图
支持单点修改 查询黑色与白色联通快个数
思路:
可以把每一行压为一个点
使用线段树来维护
然后两行合并的时候使用并查集来合并
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<algorithm> 7 #include<queue> 8 #include<vector> 9 #include<map> 10 #define ll long long 11 #define inf 2139062143 12 #define MAXN 220 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) x=x*10+ch-'0',ch=getchar(); 19 return x*f; 20 } 21 int n,g[MAXN][MAXN],f[MAXN<<2],t[MAXN<<2]; 22 int find(int x) {return f[x]==x?x:f[x]=find(f[x]);} 23 struct data {int ans[2],m[MAXN<<1];}tr[MAXN<<2]; 24 void solve(int k,int p) 25 { 26 tr[k].ans[g[p][1]]=1,tr[k].ans[g[p][1]^1]=0,tr[k].m[1]=tr[k].m[1+n]=1; 27 for(int i=2,j=1;i<=n;i++) 28 { 29 if(g[p][i]!=g[p][j]) tr[k].ans[g[p][i]]++,j=i; 30 tr[k].m[i]=tr[k].m[i+n]=j; 31 } 32 } 33 void upd(int k,int p) 34 { 35 tr[k].ans[0]=tr[k<<1].ans[0]+tr[k<<1|1].ans[0]; 36 tr[k].ans[1]=tr[k<<1].ans[1]+tr[k<<1|1].ans[1]; 37 //cout<<k<<" "<<p<<endl; 38 for(int i=1;i<=n*2;i++) f[i]=tr[k<<1].m[i]; 39 //for(int i=1;i<=n*2;i++) cout<<i<<" "<<f[i]<<" "<<tr[k<<1].m[i]<<endl; 40 for(int i=1;i<=n*2;i++) f[i+n*2]=tr[k<<1|1].m[i]+n*2; 41 //cout<<f[1]<<" "<<f[2]<<endl; 42 for(int i=1;i<=n;i++) if(g[p][i]==g[p+1][i]&&find(i+n)!=find(i+n*2))tr[k].ans[g[p][i]]--,f[f[i+n]]=f[i+n*2]; 43 for(int i=1;i<=n*4;i++) 44 { 45 f[i]=find(i); 46 if(i>n*3) t[f[i]]=i-n*2; 47 } 48 for(int i=1;i<=n;i++) tr[k].m[i]=i; 49 for(int i=1;i<=n;i++) tr[k].m[i+n]=t[f[i+n*3]]; 50 } 51 void build(int k,int l,int r) 52 { 53 if(l==r) {solve(k,l);return;} 54 int mid=(l+r)>>1; 55 build(k<<1,l,mid),build(k<<1|1,mid+1,r); 56 upd(k,mid); 57 } 58 void mdf(int k,int l,int r,int x) 59 { 60 if(l==r) {solve(k,l);return;} 61 int mid=(l+r)>>1; 62 if(x<=mid) mdf(k<<1,l,mid,x); 63 else mdf(k<<1|1,mid+1,r,x); 64 upd(k,mid); 65 } 66 int main() 67 { 68 n=read();int a,b; 69 for(int i=1;i<=n;i++) 70 for(int j=1;j<=n;j++) g[i][j]=read(); 71 build(1,1,n); 72 int T=read(); 73 while(T--) a=read(),b=read(),g[a][b]^=1,mdf(1,1,n,a),printf("%d %d\n",tr[1].ans[1],tr[1].ans[0]); 74 }