题意:给出$N,M$,试构造一个$N \times M$的非全$0$矩阵,其中所有格子都满足:它和它上下左右四个格子的权值之和为偶数。$N , M \leq 40$
可以依据题目中的条件列出有$N \times M$的元、$N \times M$个方程的异或方程组(异或方程组就是所有位置都是$1$或$0$,最右边一列的答案需要通过异或互相消除的方程组,一般在$mod\,2$意义下产生)。
理论上元和方程组数量一致的时候每一个元都是有唯一解的,但是在有解的情况下,其中一些方程是线性相关的,这意味着消到最后,某一些行会变成全$0$(如果不是很清楚可以像$vegetable chicken$我一样打一波$3 \times 3$和$4 \times 4$的表)。我们可以把行全$0$的元(又称之为*元)全部设为$1$,因为它们是多少对方程最后有无解没有关系,然后一步步把上面推出来即可。
因为复杂度为$1600^3$平常的高斯消元速度很慢,所以可以用神仙$STL\,bitset$优化
#include<bits/stdc++.h> using namespace std; inline int read(){ ; ; char c = getchar(); while(c != EOF && !isdigit(c)){ if(c == '-') f = ; c = getchar(); } while(c != EOF && isdigit(c)){ a = (a << ) + (a << ) + (c ^ '); c = getchar(); } return f ? -a : a; } ][] = {,,,-,,,-,,,}; bitset < > gauss[] , ans; int main(){ #ifdef LG freopen("3164.in" , "r" , stdin); freopen("3164.out" , "w" , stdout); #endif int M , N; cin >> M >> N; ; i < M ; i++) ; j < N ; j++) ; k < ; k++) ] >= && i + dir[k][] < M && j + dir[k][] >= && j + dir[k][] < N) gauss[i * N + j][(i + dir[k][]) * N + j + dir[k][]] = ; ; ; i < M * N ; i++){ int j = now; while(j < M * N && !gauss[j][i]) j++; if(j == M * N) continue; if(j != now) swap(gauss[now] , gauss[j]); while(++j < M * N) if(gauss[j][i]) gauss[j] ^= gauss[now]; now++; } ; i >= ; i--){ if(!gauss[i][i]) ans[i] = ; if(ans[i]) ; j >= ; j--) if(gauss[j][i]) ans[j] = ans[j] ^ ; } ; i < M ; i++){ ; j < N ; j++){ putchar(ans[i * N + j] + ); putchar(' '); } putchar('\n'); } ; }