您的位置:首页 > 其它

bzoj 1453: [Wc]Dface双面棋盘

2017-08-09 11:07 197 查看

1453: [Wc]Dface双面棋盘

Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 617 Solved: 317
[Submit][Status][Discuss]

Description



Input



Output



Sample Input



Sample Output



HINT



用线段树+数组模拟并查集,维护每一列的连通性,然后暴力合并就行了,常数巨大

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 210
int father[N<<2],tmp[N<<2],n,m,a

;
struct Node{
int l,r;
int le
,ri
;
int lb
,rb
;
int s0,s1;
}tree[N<<2];

inline int find(int x){
if(father[x]!=x)father[x]=find(father[x]);
return father[x];
}
void update(int rt){
tree[rt].s0=tree[rt<<1].s0+tree[rt<<1|1].s0;
tree[rt].s1=tree[rt<<1].s1+tree[rt<<1|1].s1;
memcpy(tree[rt].lb,tree[rt<<1].lb,sizeof tree[rt].lb);
memcpy(tree[rt].rb,tree[rt<<1|1].rb,sizeof tree[rt].rb);
for(int i=1;i<=n<<2;i++) father[i]=i;
for(int i=1;i<=n;i++) tree[rt<<1|1].le[i]+=2*n,tree[rt<<1|1].ri[i]+=2*n;
for(int i=1;i<=n;i++){
int x=tree[rt<<1].ri[i],y=tree[rt<<1|1].le[i];
if(find(x)!=find(y)&&tree[rt<<1].rb[i]==tree[rt<<1|1].lb[i]){
father[find(x)]=find(y);
if(tree[rt<<1].rb[i]){
tree[rt].s1--;
}else{
tree[rt].s0--;
}
}
}
for(int i=1;i<=n;i++) tree[rt].le[i]=find(tree[rt<<1].le[i]),
tree[rt].ri[i]=find(tree[rt<<1|1].ri[i]);
for(int i=1;i<=n;i++) tmp[i<<1]=tree[rt].le[i],tmp[(i<<1)-1]=tree[rt].ri[i];
sort(tmp+1,tmp+1+2*n);
int mxdata=unique(tmp+1,tmp+1+2*n)-tmp-1;
for(int i=1;i<=n;i++) tree[rt].le[i]=lower_bound(tmp+1,tmp+1+mxdata,
tree[rt].le[i])-tmp,tree[rt].ri[i]=lower_bound(tmp+1,tmp+1+mxdata,tree[rt].ri[i])-tmp;
for(int i=1;i<=n;i++) tree[rt<<1|1].le[i]-=2*n,tree[rt<<1|1].ri[i]-=2*n;
}

void build(int l,int r,int rt){
tree[rt].l=l;tree[rt].r=r;
if(l==r){
int tot=0;
for(int i=1;i<=n;i++)
{
if(a[i][l]!=a[i-1][l])
{
tot++;
if(a[i][l]) tree[rt].s1++;
else tree[rt].s0++;
}
tree[rt].le[i]=tree[rt].ri[i]=tot;
tree[rt].lb[i]=tree[rt].rb[i]=a[i][l];
}
return;
}
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
update(rt);
}

void modify(int rt,int pos)
{
if(tree[rt].l==tree[rt].r)
{
int tot=0;tree[rt].s1=0;tree[rt].s0=0;
for(int i=1;i<=n;i++)
{
if(a[i][pos]!=a[i-1][pos])
{
tot++;
if(a[i][pos]) tree[rt].s1++;
else tree[rt].s0++;
}
tree[rt].le[i]=tree[rt].ri[i]=tot;
tree[rt].lb[i]=tree[rt].rb[i]=a[i][pos];
}
return;
}
int mid=(tree[rt].l+tree[rt].r)>>1;
if(pos<=mid) modify(rt<<1,pos);
else modify(rt<<1|1,pos);
update(rt);
}

int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
a[0][i]=-1;
for(int j=1;j<=n;j++){
scanf("%d",&a[i][j]);
}
}
build(1,n,1);
scanf("%d",&m);
while(m--){
int x,y;
scanf("%d%d",&x,&y);
a[x][y]^=1;
modify(1,y);
printf("%d %d\n",tree[1].s1,tree[1].s0);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: