题意:
给一个n * n的矩阵A 和 B,求有多少个矩阵C能使A x C = B ⊙ C???
输入描述:
输入n和01矩阵A和01矩阵B
1 <= n <=200
输出描述:
Output the answer module 998244353
输入
2
0 1
1 1
1 0
0 1
输出
2
思路:
对于矩阵C的每一列考虑,其实就是异或方程组的高斯消元
但是在赛场上高斯消元我不会啊…
代码实现:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e2 + 5;
const ll mod = 998244353;
int n;
int A[maxn][maxn];
int B[maxn][maxn];
int a[maxn][maxn];//增广矩阵
int x[maxn];//解集
int freeX[maxn];//自由变元
ll qpow(ll x,ll y){//快速幂
ll res = 1;
while(y){
if(y & 1) res = (res * x) % mod;
y >>= 1;
x = (x * x) % mod;
}
return res % mod;
}
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){
for(int j = row;j < var + 1;j++){
swap(a[row][j],a[maxRow][j]);
}
}
if(a[row][col] == 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++){
a[i][j] ^= a[row][j];
}
}
}
}
for(int i = row;i < equ;i++){
if(a[i][col] != 0){
return -1;
}
}
int tmp = var - row;
if(row < var){
return tmp;
}
return 0;
}
void init(){
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++){
a[i][j] = A[i][j];
}
}
}
int main(){
scanf("%d",&n);
memset(a,0,sizeof(a));
memset(B,0,sizeof(B));
memset(A,0,sizeof(A));
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]);
}
}
ll ans = 1;
for(int i = 0;i < n;i++){
init();
for(int j = 0;j < n;j++){
a[j][j] = (A[j][j] - B[j][i] + 2) % 2;
}
int freeNum = Gauss(n,n);
if(freeNum == -1) continue;
ans = (ans * qpow(2,freeNum)) % mod;
}
printf("%lld\n",ans);
return 0;
}