#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 210;
const ll mod = 998244353;
int a[maxn][maxn]; //增光矩阵
int x[maxn]; //解集
int freeX[maxn]; //自由bianyuan
ll qpow(ll a, ll b)
{
ll ans = 1;
while (b > 0)
{
if (b & 1)
ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
}
int Gauss(int equ, int var)
{
for (int i = 0; i <= var; i++)
{
x[i] = 0;
freeX[i] = 0;
}
int col = 0; //当前处理的列
int num = 0; //自由变元的序号
int row; //当前处理的行
for (row = 0; row < equ && col < var; row++, col++)
{ //枚举当前处理的行
int maxRow = row; //当前列绝对值最大的行
for (int i = row + 1; i < equ; i++)
{ //寻找当前列绝对值最大的行
if (abs(a[i][col]) > abs(a[maxRow][col]))
maxRow = i;
}
if (maxRow != row)
{ //与第row行交换
for (int j = row; j < var + 1; j++)
swap(a[row][j], a[maxRow][j]);
}
if (a[row][col] == 0)
{ // col列第row行以下全是0,处理当前行的下一列
freeX[num++] = col; //记录自由变元
row--;
continue;
}
for (int i = row + 1; i < equ; i++)
{
if (a[i][col] != 0)
{
for (int j = col; j < var + 1; j++)
{ //对于下面出现该列中有1的行,需要把1消掉
a[i][j] ^= a[row][j];
}
}
}
}
for (int i = row; i < equ; i++)
if (a[i][col] != 0)
return -1;
int temp = var - row; //自由变元有var-row个
if (row < var) //返回自由变元数
return temp;
return 0;
}
int A[maxn][maxn], B[maxn][maxn];
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> A[i][j];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> B[i][j];
ll ans = 1;
for (int j = 0; j < n; j++)
{
for (int i = 0; i < n; i++)
{
for (int k = 0; k < n; k++)
{
a[i][k] = A[i][k];
}
}
for (int i = 0; i < n; i++)
{
a[i][i] = (A[i][i] - B[i][j] + 2) % 2;
}
int r = Gauss(n, n);
if (r == -1)
{
ans = 0;
break;
}
ans *= qpow(2, r);
ans %= mod;
}
printf("%lld\n", ans);
return 0;
}
后期手打中
晚安💤