Matrix Equation

Matrix Equation

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;
}
posted @ 2021-11-09 21:53  sora_013  阅读(43)  评论(0编辑  收藏  举报