zoukankan      html  css  js  c++  java
  • Matrix Equation (2020icpc济南)

    A、Matrix Equation

    题意:
    给定两个 (n imes n)(01)矩阵(A),(B),求(01)矩阵 (C)种数,其中 (C) 满足 (A imes C = Bodot C)
    (Z = X imes Y) ,即表示 ({Z_{i,j}} = (sum^{n}_{k=1} X_{i,k}Y_{k,j} ) mod 2)
    (S = Xodot Y) ,即表示 ({S_{i,j}} = X_{i,j}Y_{i,j})

    思路:
    首先,考虑 (C) 矩阵的元素只由$ 0 1 $组成,每个 (C) 矩阵中的未知数都可以通过 (A、B) 两个矩阵表示成一些方程组,考虑高斯消元法,那么即如果某个位置都未知数是确定的,则方法数不变,如果是自由变元,即不能确定的,那么方法数$ imes 2$(因为该位置有两种可能取值,即0或1)。
    在使用高斯消元法求解过程中,我们发现如果设置 (n imes n) 个未知量,那么时间复杂度必定会爆炸,接下来考虑上面都式子,我们发现两个式子都是列独立的,即 (C) 中每一列的所有未知量可以单独构成n个方程组,这一列与其他列的未知量是无关的,可以推出方乘(以第一列为例)
    (egin{cases}A_{1,1} imes C_{1,1}+A_{1,2} imes C_{2,1}+ ...+A_{1,n} imes C_{n,1} = B_{1,1} imes C_{1,1}\A_{2,1} imes C_{1,1}+A_{2,2} imes C_{2,1}+ ...+A_{2,n} imes C_{n,1} = B_{2,1} imes C_{2,1}\ ......\ ......\ A_{3,1} imes C_{1,1}+A_{3,2} imes C_{2,1}+ ...+A_{3,n} imes C_{n,1} = B_{n,1} imes C_{n,1} \end{cases})
    然后把右边移动到左边,由左边各未知数的系数作为增广矩阵,最后用高斯消元法,一列列的求出各列中自由变元的数量即可。
    最终答案即是 (2^{ans} mod 998244353)

    代码:

    const int N = 205;
    const ll mod=998244353;
    ll A[N][N],B[N][N];
    ll ma[N][N];
    ll x[N];
    ll n;
    bool freeX[N];
    //有equ个方程,var个变元。增广矩阵行数为equ,列数为var+1
    ll Gauss(ll equ, ll val){
        ll r = 1, ans = 0;
        for(int c = 1; c <= n; c++)
        {
            ll now = r;
            for(int i = r; i <= n; i++)
            {
                if(ma[i][c])
                {
                    now = i;
                    break;
                }
            }
            if(!ma[now][c])  
            {
                ans++;
                continue;
            }
            for(int i = c; i <= n; i++)
                swap(ma[now][i], ma[r][i]);
            //Print(mc);
            for(int i = r + 1; i <= n; i++)
            {
                if(ma[i][c])
                    for(int j = c; j <= n; j++)
                        ma[i][j] ^= ma[r][j];
            }
            //Print(mc);
            r++;
        }
        return ans;
    }
     
    ll qpow(ll a,ll b,ll mod)
    {
        ll ans=1;
        while(b){
            if(b&1){
                ans=ans*a;
                ans=ans%mod;
            }
            a=a*a;
            a=a%mod;
            b/=2;
        }
        return ans%mod;
    }
    void init()
    {
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                ma[i][j]=A[i][j];
            }
        }
     }
    int main()
    {
        ll equ,var;  //equ个方程,var个变元
        scanf("%lld",&n);
        equ=n;
        var=n;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%lld",&A[i][j]);
                ma[i][j]=A[i][j];
            }
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                scanf("%lld",&B[i][j]);
            }
        }
        ll ans=1;
        for(int j=1;j<=n;j++)
        {  
            init();
            for(int i=1;i<=n;i++){
                ma[i][i]=(A[i][i]-B[i][j]+2)%2;
                ma[i][n+1]=0;
            }
            ll freenum=Gauss(equ,var);
            if(freenum==-1) continue;
            //cout<<freenum<<endl;
            ans*=qpow(2,freenum,998244353);
            ans=ans%mod;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    
    
    越自律,越自由
  • 相关阅读:
    oracle lengthb
    layui-rp
    1709052基于框架新建 子项目
    echar 常用单词
    Leetcode 481.神奇字符串
    Leetcode 480.滑动窗口中位数
    Leetcode 479.最大回文数乘积
    Leetcode 477.汉明距离总和
    Leetcode 476.数字的补数
    Leetcode 475.供暖气
  • 原文地址:https://www.cnblogs.com/ha-chuochuo/p/14300360.html
Copyright © 2011-2022 走看看