题意:
定
义
两
种
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;
}