首页 > 代码库 > 1453: [Wc]Dface双面棋盘 (线段树+并茶几)
1453: [Wc]Dface双面棋盘 (线段树+并茶几)
Description
Input
Output
Sample Input
Sample Output
HINT
1 /* 2 线段树+并查集维护 3 线段树维护每列的信息 4 le 代表区间左端一列连通性的信息 5 ri 代表区间右端一列连通性的信息 6 w,b 分别代表白色连通块和黑色连通块的个数 7 lb 代表区间左端一列黑白点的信息 8 rb 代表区间右端一列黑白点的信息 9 tmp用来暂时存储连通块个数 10 */ 11 #include<cstdio> 12 #include<cstring> 13 #include<iostream> 14 #include<algorithm> 15 #define MAXN 210 16 17 using namespace std; 18 19 struct node { 20 int l,r; 21 int w,b; 22 int le[MAXN],ri[MAXN]; 23 int lb[MAXN],rb[MAXN]; 24 }; 25 node t[MAXN<<2]; 26 27 int a[MAXN][MAXN],n,m; 28 29 int fa[MAXN<<2],tmp[MAXN<<2]; 30 31 inline void read(int&x) { 32 int f=1;x=0;char c=getchar(); 33 while(c>‘9‘||c<‘0‘) {if(c==‘-‘) f=-1;c=getchar();} 34 while(c>=‘0‘&&c<=‘9‘) {x=(x<<1)+(x<<3)+c-48;c=getchar();} 35 x=x*f; 36 } 37 38 inline int find(int x) { 39 if(x==fa[x]) return fa[x]; 40 else return fa[x]=find(fa[x]); 41 } 42 43 inline void up(int now) { 44 t[now].w=t[now<<1].w+t[now*2+1].w; 45 t[now].b=t[now<<1].b+t[now*2+1].b; 46 memcpy(t[now].lb,t[now<<1].lb,sizeof t[now].lb); 47 memcpy(t[now].rb,t[now*2+1].rb,sizeof t[now].rb); 48 for(int i=1;i<=3*n;i++) fa[i]=i; 49 for(int i=1;i<=n;i++) 50 t[now*2+1].le[i]+=2*n,t[now*2+1].ri[i]+=2*n; 51 for(int i=1;i<=n;i++) { 52 int x=t[now<<1].ri[i],y=t[now*2+1].le[i]; 53 if(find(x)!=find(y)&&t[now<<1].rb[i]==t[now*2+1].lb[i]) { 54 fa[find(x)]=find(y); 55 if(t[now<<1].rb[i]) t[now].b--; 56 else t[now].w--; 57 } 58 } 59 for(int i=1;i<=n;i++) 60 t[now].le[i]=find(t[now<<1].le[i]),t[now].ri[i]=find(t[now*2+1].ri[i]); 61 for(int i=1;i<=n;i++) 62 tmp[i<<1]=t[now].le[i],tmp[(i<<1)-1]=t[now].ri[i]; 63 sort(tmp+1,tmp+1+2*n); 64 int maxdata=http://www.mamicode.com/unique(tmp+1,tmp+1+2*n)-tmp-1; 65 for(int i=1;i<=n;i++) 66 t[now].le[i]=lower_bound(tmp+1,tmp+1+maxdata,t[now].le[i])-tmp,t[now].ri[i]=lower_bound(tmp+1,tmp+1+maxdata,t[now].ri[i])-tmp; 67 for(int i=1;i<=n;i++) t[now*2+1].le[i]-=2*n,t[now*2+1].ri[i]-=2*n; 68 return; 69 } 70 71 void build_tree(int now,int l,int r) { 72 t[now].l=l; 73 t[now].r=r; 74 if(l==r) { 75 int tot=0; 76 for(int i=1;i<=n;i++) { 77 if(a[i][l]!=a[i-1][l]) { 78 tot++; 79 if(a[i][l]) t[now].b++; 80 else t[now].w++; 81 } 82 t[now].le[i]=t[now].ri[i]=tot; 83 t[now].lb[i]=t[now].rb[i]=a[i][l]; 84 } 85 return; 86 } 87 int mid=(l+r)>>1; 88 build_tree(now<<1,l,mid); 89 build_tree(now*2+1,mid+1,r); 90 up(now); 91 } 92 93 void modify(int now,int pos) { 94 if(t[now].l==t[now].r) { 95 int tot=0; 96 t[now].b=0; 97 t[now].w=0; 98 for(int i=1;i<=n;i++) { 99 if(a[i][pos]!=a[i-1][pos]) {100 tot++;101 if(a[i][pos]) t[now].b++;102 else t[now].w++;103 }104 t[now].le[i]=t[now].ri[i]=tot;105 t[now].lb[i]=t[now].rb[i]=a[i][pos];106 }107 return;108 }109 int mid=(t[now].l+t[now].r)>>1;110 if(pos<=mid) modify(now<<1,pos);111 else modify(now*2+1,pos);112 up(now);113 }114 115 int main() {116 read(n);117 for(int i=1;i<=n;i++) {118 a[0][i]=-1;119 for(int j=1;j<=n;j++)120 read(a[i][j]);121 }122 build_tree(1,1,n);123 read(m);124 for(int i=1;i<=m;i++) {125 int x,y;126 read(x);read(y);127 a[x][y]^=1;128 modify(1,y);129 printf("%d %d\n",t[1].b,t[1].w);130 }131 return 0;132 }
1453: [Wc]Dface双面棋盘 (线段树+并茶几)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。