Matrix Equation
Matrix Equation
Problem link
https://ac.nowcoder.com/acm/contest/21858/A
Solution
Since \(A \times B = B \odot C\),then any column of these two matricies are equal.
which means that
\[\forall i,j \ A \times B (i:j) = B \odot C(i:j) \\
B \odot C(i:j) = D \times C(i) \\
(A - D) \times C(i) = 0
\]
let$ \ D = diag{b_{i1},b_{i2},...,b_{in}} \$
\(C(i)\) means the \(i\) th column of the matrix \(C\).
so we know that the number of \(C(i)\) is equal to \(2^{n - rank(A-D)}\)
so we need to calculate the rank of matrix \(A - D\)
then we need the amazing Gauss method to solve it.(of course you have learnt linear algebra and i don't need to explain what Gauss method is )
so here's the code,pay attention to that our \(+ ,\times\) are both in the meaning of \(mod \ 2\),so we need to use \(inv\) funtion.
#include <bits/stdc++.h>
using namespace std;
const int maxn = 207;
const int MOD = 2;
typedef long long ll;
ll qPow(ll x,ll y,ll mod){
ll ans = 1;
while(y > 0){
if(y & 1){
ans = ans * x % mod;
y--;
}
x = x * x % mod;
y /= 2;
}
return ans % mod;
}
int exGcd(int a,int b,int &x,int &y){
if(a == 0 && b == 0) return -1;
if(b == 0){
x = 1;
y = 0;
return a;
}
int d = exGcd(b,a%b,y,x);
y -= a/b * x;
return d;
}
int inv(int a,int mod){
a = (a%mod + mod) % mod;
int x,y;
int d = exGcd(a,mod,x,y);
if(d == 1) return (x%mod + mod) % mod;
else return -1;
}
struct Matrix{
int n,m;
int M[maxn][maxn];
Matrix();
Matrix(int __n,int __m);
void input();
void output();
int getN();
int getM();
int getRank();
void rowChange(int a,int k);
void rowSwap(int a,int b);
void rowAdd(int a,int b,int k);
void simplify();
};
Matrix::Matrix() {}
Matrix::Matrix(int __n, int __m) {
n = __n;
m = __m;
}
void Matrix:: input(){
for(int i = 0;i < n; ++i){
for(int j = 0; j < m; ++j){
cin >> M[i][j];
}
}
}
void Matrix:: output(){
for(int i = 0;i < n; ++i){
for(int j = 0; j < m; ++j){
cout << M[i][j] << " \n"[j == m-1];
}
}
}
int Matrix::getN(){return n;}
int Matrix::getM() {return m;}
int Matrix::getRank(){
int ret = 0,j = 0;
Matrix x = *this;
x.simplify();
for(int i = 0;i < n; ++i){
while(j < m && x.M[i][j] == 0) j++;
if(j >= m) break;
ret++;
}
return ret;
}
void Matrix::rowChange(int a,int k){
for(int i = 0;i < m; ++i){
M[a][i] *= k;
M[a][i] %= MOD;
}
}
void Matrix::rowSwap(int a,int b){
for(int i = 0;i < m; ++i){
swap(M[a][i],M[b][i]);
}
}
void Matrix::rowAdd(int a,int b,int k){
for(int i = 0;i < m; ++i){
M[b][i] += M[a][i] * k;
M[b][i] %= MOD;
M[b][i] = (M[b][i] + MOD) % MOD;
}
}
void Matrix::simplify() {
int j,rank = 0;
for(int i = 0;i < m; ++i){
j = rank;
while(j < n && M[j][i] == 0) j++;
if(j == n) continue;
rowSwap(rank,j);
rowChange(rank,inv(M[rank][i],MOD));
for(int k = rank + 1; k < n; ++k){
if(M[k][i] != 0){
rowAdd(rank,k,-M[k][i]);
}
}
rank++;
}
for(int i = n-1 ;i >= 0; --i){//Simplify to the most simple format
for(int j = 0;j < m; ++j){
if(M[i][j] == 1){
for(int k = 0; k < i ; ++k){
if(M[k][j] != 0)
rowAdd(i,k,-inv(M[k][j],MOD));
}
break;
}
}
}
}
int n;
Matrix A,B;
int main(){
cin >> n;
A = Matrix(n,n);
B = Matrix(n,n);
A.input();
B.input();
ll ans = 0;
for(int i = 0;i < n; ++ i){
Matrix _A = A;
for(int j = 0;j < n; ++j){
_A.M[j][j] =(_A.M[j][j] - B.M[j][i] + 2) % 2;
}
ans += n - _A.getRank();
}
cout << qPow(2, ans,998244353) % 998244353<< endl;
}