bzoj 3603

考虑转化问题:一个点相邻元素中有偶数个$1$等价于一个点与相邻元素异或和为$0$

于是直接列出异或方程组求解即可

注意由于要求不允许出现全0矩阵,因此如果有自由元直接给成$1$

贴代码:

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <bitset>
using namespace std;
bitset <1605> a[1605];
int n,m,N;
int ret[1605];
int to[5][2]={{0,0},{1,0},{0,1},{-1,0},{0,-1}};
int idx(int x,int y)
{
    return (x-1)*m+y;
}
bool check(int x,int y)
{
    return x>0&&x<=n&&y>0&&y<=m;
}
void Gauss()
{
    for(int i=1;i<=N;i++)
    {
        int temp=i;
        while(!a[temp][i]&&temp<=N)temp++;
        if(temp==N+1)
        {
            for(int j=i+1;j<=N;j++)a[i][j]=0;
            a[i][N+1]=1;
            continue;
        }
        swap(a[i],a[temp]);
        for(int j=i+1;j<=N;j++)if(a[j][i])a[j]^=a[i];
    }
    for(int i=N;i>=1;i--)
    {
        ret[i]=a[i][N+1];
        for(int j=i+1;j<=N;j++)if(a[i][j])ret[i]^=ret[j];
    }
}
int main()
{
    scanf("%d%d",&n,&m),N=n*m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            for(int k=0;k<5;k++)
            {
                int toi=i+to[k][0],toj=j+to[k][1];
                if(check(toi,toj))a[idx(i,j)][idx(toi,toj)]=1;
            }
        }
    }
    Gauss();
    for(int i=1;i<=n;i++,printf("\n"))for(int j=1;j<=m;j++)printf("%d ",ret[idx(i,j)]);
    return 0;
}

 

posted @ 2019-07-11 15:45  lleozhang  Views(78)  Comments(0Edit  收藏
levels of contents