题意:
定 义 两 种 01 矩 阵 矩 阵 运 算 : 定义两种01矩阵矩阵运算: 定义两种01矩阵矩阵运算:
( 1 ) Z = X × Y , Z i , j = ( ∑ k = 1 n X i , k Y k , j ) % 2 (1)Z=X×Y,Z_{i,j}=(\sum_{k=1}^nX_{i,k}Y_{k,j})\%2 (1)Z=X×Y,Zi,j=(∑k=1nXi,kYk,j)%2
( 2 ) Z = X ⊙ Y , Z i , j = X i , j Y i , j (2)Z=X⊙Y,Z_{i,j}=X_{i,j}Y_{i,j} (2)Z=X⊙Y,Zi,j=Xi,jYi,j
给 定 n ∗ n 的 01 矩 阵 矩 阵 A 和 B 给定n*n的01矩阵矩阵A和B 给定n∗n的01矩阵矩阵A和B
问 有 多 少 个 n ∗ n 的 01 矩 阵 矩 阵 C , 满 足 A × C = B ⊙ C 问有多少个n*n的01矩阵矩阵C,满足A×C=B⊙C 问有多少个n∗n的01矩阵矩阵C,满足A×C=B⊙C
数 据 范 围 : n < = 200 数据范围:n<=200 数据范围:n<=200
解法:
A × C = B ⊙ C A×C=B⊙C A×C=B⊙C
∑ k = 1 n A i , k C k , j = B i , j C i , j \sum_{k=1}^nA_{i,k}C_{k,j}=B_{i,j}C_{i,j} ∑k=1nAi,kCk,j=Bi,jCi,j
对 于 每 一 个 j , 有 : 对于每一个j,有: 对于每一个j,有:
( A 1 , 1 C 1 , j + A 1 , 2 C 2 , j + . . . . A 1 , n C n , j ) % 2 = B 1 , j C 1 , j (A_{1,1}C_{1,j}+A_{1,2}C_{2,j}+....A_{1,n}C_{n,j})\%2=B_{1,j}C_{1,j} (A1,1C1,j+A1,2C2,j+....A1,nCn,j)%2=B1,jC1,j
( A 2 , 1 C 2 , j + A 2 , 2 C 2 , j + . . . . A 2 , n C n , j ) % 2 = B 2 , j C 2 , j (A_{2,1}C_{2,j}+A_{2,2}C_{2,j}+....A_{2,n}C_{n,j})\%2=B_{2,j}C_{2,j} (A2,1C2,j+A2,2C2,j+....A2,nCn,j)%2=B2,jC2,j
. . . ... ...
% 2 加 法 就 是 异 或 , 所 以 式 子 可 以 变 成 : \%2加法就是异或,所以式子可以变成: %2加法就是异或,所以式子可以变成:
A 1 , 1 C 1 , j ⊕ A 1 , 2 C 2 , j ⊕ . . . . A 1 , n C n , j = B 1 , j C 1 , j A_{1,1}C_{1,j}⊕A_{1,2}C_{2,j}⊕....A_{1,n}C_{n,j}=B_{1,j}C_{1,j} A1,1C1,j⊕A1,2C2,j⊕....A1,nCn,j=B1,jC1,j
A 2 , 1 C 1 , j ⊕ A 2 , 2 C 2 , j ⊕ . . . . A 2 , n C n , j = B 2 , j C 2 , j A_{2,1}C_{1,j}⊕A_{2,2}C_{2,j}⊕....A_{2,n}C_{n,j}=B_{2,j}C_{2,j} A2,1C1,j⊕A2,2C2,j⊕....A2,nCn,j=B2,jC2,j
. . . ... ...
如 果 B i , j = 0 , 那 么 式 子 右 边 就 是 0 如果B_{i,j}=0,那么式子右边就是0 如果Bi,j=0,那么式子右边就是0
如 果 B i , j = 1 , 那 么 左 右 同 时 异 或 C 2 , j , 如果B_{i,j}=1,那么左右同时异或C_{2,j}, 如果Bi,j=1,那么左右同时异或C2,j,
右 边 变 成 0 , 左 边 a i , i = 1 右边变成0,左边a_{i,i}=1 右边变成0,左边ai,i=1
那 么 式 子 右 边 就 变 成 0 , 左 边 的 A j , j = A j , j ⊕ 1 那么式子右边就变成0,左边的A_{j,j}=A_{j,j}⊕1 那么式子右边就变成0,左边的Aj,j=Aj,j⊕1
对 于 每 个 j , 用 高 斯 消 元 分 别 计 算 出 异 或 方 程 组 自 由 元 的 个 数 对于每个j,用高斯消元分别计算出异或方程组自由元的个数 对于每个j,用高斯消元分别计算出异或方程组自由元的个数
设 n 列 的 自 由 元 总 个 数 为 c n t , 那 么 答 案 为 2 c n t 设n列的自由元总个数为cnt,那么答案为2^{cnt} 设n列的自由元总个数为cnt,那么答案为2cnt
code:
#include <bits/stdc++.h>
using namespace std;
const int maxm=1e3+5;
const int mod=998244353;
int ppow(int a,int b,int mod){
int ans=1%mod;a%=mod;
for(;b;b>>=1,a=1LL*a*a%mod)if(b&1)ans=1LL*ans*a%mod;
return ans;
}
int A[maxm][maxm];
int B[maxm][maxm];
int n;
//
int a[maxm][maxm],x[maxm];
int freedom[maxm],num;//存储自由元的位置
int Gauss(int m,int n){
//m为行数,n为列数(不含常数列)
int col=0,k=0;//col为列号,k为行号
for(;k<m&&col<n;k++,col++){
int r=k;
for(int i=k+1;i<m;i++){
//找系数最大的列
if(abs(a[i][col])>a[r][col])r=i;
}
if(a[r][col]==0){
//如果一列都为0就跳过
freedom[num++]=col;//存储自由元的列数
k--;continue;
}
if(r!=k)for(int i=col;i<=n;i++){
//交换行
swap(a[k][i],a[r][i]);
}
for(int i=k+1;i<m;i++){
//消元
if(abs(a[i][col])!=0){
for(int j=col;j<=n;j++){
a[i][j]^=a[k][j];
}
//a[i][j]=0;
}
}
}
for(int i=k;i<m;i++){
if(a[i][col]!=0)return -1;//无解标志
}
if(k<n)return n-k;//如果有自由元,返回自由元个数
for(int i=n-1;i>=0;i--){
x[i]=a[i][n];
for(int j=i+1;j<n;j++){
x[i]^=(a[i][j]&&x[j]);
}
}
return 0;//有解标志
}
signed main(){
scanf("%d",&n);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
scanf("%d",&A[i][j]);
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
scanf("%d",&B[i][j]);
}
}
int cnt=0;
for(int p=0;p<n;p++){
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
a[i][j]=A[i][j];
}
if(B[i][p]==1)a[i][i]^=1;
}
int temp=Gauss(n,n);
if(temp==-1){
puts("0");
return 0;
}
cnt+=temp;
}
int ans=ppow(2,cnt,mod);
printf("%d\n",ans);
return 0;
}