Determinant

原题:Determinant

原题大意

给出n × (n-1) 的矩阵,要求从左到右,依次去掉一列后,剩余行列式的值,同时答案mod1e9+7。

算法分析

仔细分析后发现是求伴随矩阵的原值(不要求根据行和列的奇偶改变符号),根据方阵的公式:由逆矩阵和行列式值的乘积,可以求出伴随矩阵。

所以先将矩阵补成n × n的(随机补全排除偶然性,否则可能有其他其他情况,比如不存在逆矩阵,行列式值为0),我补的是最下面一行(哪一行这个也任意)。关于求逆矩阵,先将原矩阵变成n ×(2n),并且右边是单位矩阵,将左边的变成单位矩阵,右边的就是逆矩阵。

所以这里用到了高斯消元,但是由于是mod运算,所以不能用double,加减乘要mod,除就是乘以逆元,最后得到的矩阵乘以行列式的值,最后一列就是我们要求的答案,并且根据行列的和的奇偶将值改回来,所以依次输出最后一列的值。

程序代码

#include <bits/stdc++.h>
using namespace std;
const int maxn = 202;
typedef long long ll;
const ll mod = 1e9+7;
typedef ll Matrix[maxn][maxn * 2];
int n;
ll pow_mod(ll a, ll p){
    ll ans = 1;
    while(p){
        if(p & 1) ans = ans * a % mod;
        a = a * a % mod;
        p >>= 1;
    }
    return ans;
}
ll exgcd(ll a,ll b,ll &x,ll &y)  
{  
    if(!b)  
    {  
        x = 1;  
        y = 0;  
        return a;  
    }  
    else  
    {  
        ll r = exgcd(b,a%b,y,x);  
        y -= x * (a/b);  
        return r;  
    }  
}  
ll lcm(ll a,ll b)  
{  
    ll x = 0, y =0;  
    return a / exgcd(a,b,x,y) * b;  
}
void gauss_jordan_elimination(Matrix A, int n,ll & _A){//_A是行列式的值
    int i, j, k, r;
    ll cnt = 0;

    //变成上三角
    for(i = 1; i <= n; i++){
        r = i;
        for(j = i+1; j <= n; j++)
            if(abs(A[j][i]) > abs(A[r][i])) r = j;
            //cnt记录交换次数
        if(r != i) {cnt++;for(j = 1; j <= n*2; j++) swap(A[r][j], A[i][j]);}
        for(k = i+1; k <= n; k++)if(A[k][i]){
            ll d = lcm(A[k][i],A[i][i]);
            ll t1 = d/A[k][i], t2 = d/A[i][i];
            ll inv = pow_mod(t1,mod-2);
            for(j = i; j <= n*2; j++) {A[k][j] = ((A[k][j] * t1-  A[i][j] * t2)%mod + mod) % mod; A[k][j] = (A[k][j]*inv) % mod;}
        }
    }
    _A = 1;
    for(i = 1; i <= n; i++)
        _A = (_A*A[i][i]) % mod;
    if(cnt % 2 == 1) _A = mod - _A;

    //变成单位矩阵
    for(i = n; i >= 1; i--){
        ll inv = pow_mod(A[i][i],mod-2);
        for(j = i; j <= n*2; j++)
           A[i][j] = (A[i][j] * inv) % mod;

        if(i < n){
            for(j = i+1; j <= n; j++){
                ll t = A[i][j];
                for(k = j; k <= n*2; k++)
                {
                    A[i][k] = ((A[i][k] - t * A[j][k])%mod+mod)%mod;
                }
            }
        }
    }
}
int main(){
//freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin.tie(0);
    Matrix A;
    srand((unsigned int )time(NULL));
    while(cin >> n){
        memset(A,0,sizeof(A));
        for(int i = 1; i <= n-1; i++)
            for(int j = 1; j <= n; j++)
                cin >> A[i][j];
        for(int j = 1; j <= n; j++)
            A[n][j] = rand()%maxn;
        for(int i = 1; i <= n; i++)
            A[i][n+i] = 1;
        ll _A;
        gauss_jordan_elimination(A,n,_A);
        for(int i = 1; i <= n; i++)
        {

            ll t = A[i][2*n] * _A;
            if((i+n)%2 == 1) cout << (mod-(t%mod)) % mod;
            else
                 cout << t % mod;
             if(i!=n) cout << " ";
        }
        cout << endl;
    }

    return 0;
}