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 (n−1)×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 .
- 2≤n≤200
- 0≤Bi,j<109+7
- The sum of n does not exceed 2000 .
Output
For each case, output n integers which denote the result.
Sample Input
2 2 0 3 1 2 0 6 3 1
Sample Output
0 2 2 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;
}