xtu 1260 Determinant [2017年“嘉杰信息杯” 中国大学生程序设计竞赛全国邀请赛(湖南) A]

来源:互联网 发布:iap15w413as数据手册 编辑:程序博客网 时间:2024/05/01 13:31

Determinant

Bobo learned the definition of determinant det(A) of matrix A in ICPCCamp. He also knew determinant can be computed in O(n3) using Gaussian Elimination.

Bobo has an (n1)×n matrix B he would like to find det(Bj) modulo (109+7) for all j{1,2,,n} where Bj is the matrix after removing the j-th column from B.

Input

The input contains zero or more test cases and is terminated by end-of-file. For each test case:

The first line contains an integer n. The i-th of following n lines contains n integers Bi,1,Bi,2,,Bi,n.

  • 2n200
  • 0Bi,j<109+7
  • The sum of n does not exceed 2000.

Output

For each case, output n integers which denote the result.

Sample Input

22 031 2 06 3 1

Sample Output

0 22 1 999999998

题意: 给你一个(n - 1)行n列的行列式, 求去掉第i(1 <= i <= n)行后行列式的值.

思路: 在原有行列式上加一行, 补全成n * n的矩阵, 然后利用高斯消元求得原有矩阵的伴随矩阵. 假设求得伴随矩阵为b, 则b[i][j]就是原有行列式的余子式, b[i][1]对应的就是去掉第i行后行列式的值, 原理参加下面行列式的性质.

行列式的性质: 以三阶矩阵为例, 若 A* 为 A 的伴随矩阵, 则有:

            a11a12 a13

 A =     a21a22 a23

            a31 a32 a33

 

            A11A21 A31

A* =     A12 A22 A32

             A13 A23 A33

其中Aij是aij对应的代数余子式. 在本题中余子式A11对应的就是去掉第一行第一列后行列式的值, 由于第一行是自己增加的, 所以A11就是去掉第一列后行列式的值. 


代码如下:

#include<cstdio>#include<cstring>#include<cstdlib>#include<cmath>#include<ctime>#include<iostream>#include<algorithm>using namespace std;typedef long long ll;const int maxn = 205;const ll mod = 1e9 + 7;ll a[maxn][maxn], b[maxn][maxn];ll inv_(ll a, ll k) {    ll res = 1;    while(k){        if(k & 1) res = res * a % mod;        a = a * a % mod;        k >>= 1;    }    return res;}void solve(int n) {    memset(b, 0, sizeof b);    for(int i = 1; i <= n; i++) b[i][i] = 1;    ll det = 1;    for(int i = 1; i <= n; i++) {        int t;        for(t = i; t <= n; t++) {            if(a[t][i]) break;        }        if(t != i) det *= -1;        for(int j = 1; j <= n; j++) {            swap(a[i][j], a[t][j]);            swap(b[i][j], b[t][j]);        }        det = (det * a[i][i] % mod + mod) % mod;        ll inv = inv_(a[i][i], mod - 2); //a[i][i]的逆元        for(int j = 1; j <= n; j++) {            a[i][j] = inv * a[i][j] % mod;            b[i][j] = inv * b[i][j] % mod;        }        for(int k = 1; k <= n; k++) {            if(k == i) continue;            ll tmp = a[k][i];            for(int j = 1; j <= n; j++) {                a[k][j] = (a[k][j] - a[i][j] * tmp % mod + mod) % mod;                b[k][j] = (b[k][j] - b[i][j] * tmp % mod + mod) % mod;            }        }    }    det = (det + mod) % mod;    for(int i = 1; i <= n; i++) {        for(int j = 1; j<= n; j++) {            b[i][j] = det * b[i][j] % mod;  //将b由逆矩阵变成伴随矩阵        }    }}int main(void){    int n;    while(scanf("%d",&n)!=EOF){        for(int i = 1; i <= n; i++) a[1][i] = 1;        for(int i = 2; i <= n; i++)            for(int j = 1; j <= n; j++)                scanf("%lld", &a[i][j]);        solve(n);        for(int i = 1; i <= n; i++)            printf("%lld%c",(i & 1 ? b[i][1] : (mod - b[i][1]) % mod), i == n ? '\n' : ' ');    }    return 0;}


阅读全文
0 0