BZOJ1453——[Wc]Dface双面棋盘

来源:互联网 发布:朽木充栋梁网络剧在线 编辑:程序博客网 时间:2024/04/30 22:38

1、题意:给一个二维的黑白色棋盘,可以改变一个方块的颜色,问黑白联通块的个数。
2、分析:这个题拿过来如果暴力的玩的话,O(n2m)不tle才怪。。考虑用线段树维护连通性,把二维变成一维的线段树,线段树的每一个节点又是一维。线段树节点中就用并查集维护连通性吧,维护一个线段最左列和最右列的连通性。然后合并就行了,时间复杂度O(nmlogn),听说lct能跑的更快?

#include<map>#include<set>#include<cmath>#include<queue>#include<vector>#include<bitset>#include<string>#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define M 1000010#define LL long long#define MOD 1000000007#define inf 2147483647#define llinf 4000000000000000000ll#define For(i,x,y) for(int i=(x);i<(y);i++)#define rep(i,x,y) for(int i=(x);i<=(y);i++)#define drep(i,x,y) for(int i=(x);i>=(y);i--)inline int read(){    char ch=getchar();int x=0,f=1;    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}inline LL llread(){    char ch=getchar();LL x=0,f=1;    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}struct Node{    int fa[810],bl,wh;    inline void init(){For(i,0,810)fa[i]=i;bl=wh=0;}    inline int fi(int x){return fa[x]==x?x:fa[x]=fi(fa[x]);}    inline int mer(int x,int y){if(fi(x)!=fi(y)){fa[fi(x)]=fi(y);return 1;}return 0;}} q[1010],ext; int a[210][210],mp[810],n;inline void pushup(int l,int mid,int r,int o){    q[o].bl=q[2*o].bl+q[2*o+1].bl;q[o].wh=q[2*o].wh+q[2*o+1].wh;    rep(i,1,n)q[o].fa[i]=q[2*o].fa[i],q[o].fa[i+n]=q[2*o].fa[i+n];    rep(i,1,n)q[o].fa[i+2*n]=q[2*o+1].fa[i]+2*n,q[o].fa[i+3*n]=q[2*o+1].fa[i+n]+n*2;    rep(i,1,n)if(a[mid][i]==a[mid+1][i]){        if(a[mid][i]==0)q[o].wh-=q[o].mer(i+n,i+2*n);        else q[o].bl-=q[o].mer(i+n,i+2*n);    }rep(i,1,4*n)mp[i]=0;ext.init();    ext.bl=q[o].bl;ext.wh=q[o].wh;rep(i,1,n){        if(!mp[q[o].fi(i)])mp[q[o].fi(i)]=i;        else ext.mer(mp[q[o].fi(i)],i);        if(!mp[q[o].fi(i+3*n)])mp[q[o].fi(i+3*n)]=i+n;        else ext.mer(mp[q[o].fi(i+3*n)],i+n);     }q[o]=ext;}inline void getit(int o,int l){    rep(i,1,n)q[o].mer(i,i+n);rep(i,2,n){        if(a[l][i]==a[l][i-1])q[o].mer(i-1,i);        if(a[l][i]!=a[l][i-1]){if(a[l][i]==0)q[o].wh++;else q[o].bl++;}    }if(a[l][1]==0)q[o].wh++;else q[o].bl++;}inline void build(int l,int r,int o){    q[o].init();if(l==r){getit(o,l);return;}    int mid=(l+r)/2;build(l,mid,2*o);build(mid+1,r,2*o+1);pushup(l,mid,r,o);}inline void chan(int l,int r,int o,int x,int y){    if(l==r){a[x][y]^=1;q[o].init();getit(o,l);return;}    int mid=(l+r)/2;if(x<=mid)chan(l,mid,2*o,x,y);else chan(mid+1,r,2*o+1,x,y);    pushup(l,mid,r,o);} int main(){    n=read();rep(i,1,n)rep(j,1,n)a[i][j]=read();    build(1,n,1);int m=read();while(m--){        int x=read(),y=read();chan(1,n,1,x,y);        printf("%d %d\n",q[1].bl,q[1].wh);    }    return 0;}
1 0
原创粉丝点击