Determinant
题意是给有一个n-1行n列的矩阵
让我们求去掉任意一列,得到的行列式的值(模1e9+7),也就是n个答案
最坏的做法枚举每一列然后消元,复杂度O(n³*n),显然不太可行
可以这么做,先做一次高斯消元得到一个阶梯矩阵,然后枚举每一列,枚举到第i列,把i+1到n-1列 往上移动一格,即(做一次消元)
x x x x x x x
0 x x x x x x
0 0 x x x x x
0 0 0 x x x x
0 0 0 0 x x x
0 0 0 0 0 x x
如这样,我们当前枚举到第3列时,
x x x x x x x
0 x x x x x x
0 0 x x x x x
0 0 0 x x x x
0 0 0 0 x x x
0 0 0 0 0 x x
把第4到6列向上做一次消元,然后乘一下,
第一次写矩阵变换,有些地方忘了取模结果爆了long long
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<set>
#include<map>
#include<time.h>
#include<cstdio>
#include<vector>
#include<list>
#include<stack>
#include<queue>
#include<iostream>
#include<stdlib.h>
using namespace std;
#define LONG long long
const int INF=0x3f3f3f3f;
const LONG MOD=1e9+ 7;
const double PI=acos(-1.0);
#define clrI(x) memset(x,-1,sizeof(x))
#define clr0(x) memset(x,0,sizeof x)
#define clr1(x) memset(x,INF,sizeof x)
#define clr2(x) memset(x,-INF,sizeof x)
#define EPS 1e-10
#define lson l , mid , rt<< 1
#define rson mid + 1 ,r , (rt<<1)+1
#define root 1, m , 1
LONG matr[220][229] ;
LONG ans[220 ] ;
LONG tmp_matr[220][210] ;
LONG Q_pow(LONG a , LONG b)
{
LONG c = 1;
while(b)
{
if(b&1)
c = (c * a) % MOD ;
a = (a * a) % MOD ;
b /= 2;
}
return c ;
}
LONG Gauss (int n )
{
LONG sign = 1 ;
for(int t = 1 ; t <= n ; ++ t)
{
if(matr[t][t] == 0 )
{
for(int i = t + 1; i <= n ; ++ i)
if(matr[i][t] != 0 )
{
for(int j = 1 ; j <= n + 1 ; ++j)
swap(matr[t][j] , matr[i][j]) ;
sign = -sign ;
break ;
}
}
for(int i = t +1; i <= n ; ++ i)
{
LONG x = matr[i][t] ;
LONG y = matr[t][t] ;
if( y == 0) break ;
if( x == 0) continue ;
LONG tmp = x * Q_pow(y , MOD - 2 ) % MOD ; //这里记得取模 否则下面会爆long long
for( int j = 1 ; j <= n + 1; ++ j )
matr[i][j] = ( matr[i][j] - ( matr[t][j] * tmp % MOD ) +MOD )% MOD;
}
}
LONG res = sign ;
for(int i = 1; i<= n ;++i)
res = (res * matr[i][i] )% MOD ;
return (res + MOD )% MOD ;
}
int main()
{
//freopen("/home/weyoung/桌面/in","r",stdin);
//freopen("/home/weyoung/桌面/out2","w",stdout);
int n ;
while(cin >> n)
{
for(int i = 1 ; i <= n - 1 ; ++i)
for(int j =1 ; j <= n ;++j)
cin >> matr[i][j], matr[i][j] = (matr[i][j] + MOD ) % MOD ;
ans[n] = Gauss(n-1 ) ;
for(int t = n-1; t >= 1 ; -- t )
{
LONG res = 1;
LONG sign = 1 ;
for(int i = 1 ;i < n ; ++ i)
for(int j =1; j<= n ; ++j)
tmp_matr[i][j] = matr[i][j] ;
//
for(int j =1; j <= t-1 ; ++ j )
res = (res * tmp_matr[j][j]) % MOD ;
for(int i = t + 1; i < n ; ++ i)
{
if(tmp_matr[i-1][i] == 0)
{
sign = - sign ;
for(int j = t + 1 ; j<= n ;++j)
swap(tmp_matr[i][j] , tmp_matr[i-1][j] ) ;
}
else if(tmp_matr[i][i] == 0) continue ;
else
{
LONG x = tmp_matr[i][i] ;
LONG y = tmp_matr[i-1][i] ;
LONG temp = x * Q_pow( y , MOD - 2) % MOD ; //这里取模 否则同样会爆long long
for(int j = t+ 1 ;j <= n ;++j)
tmp_matr[i][j] = ( tmp_matr[i][j] - (tmp_matr[i-1][j] * temp % MOD ) + MOD ) % MOD ;
}
res = (res * tmp_matr[i-1][i]) % MOD ;
}
res = ( (res * sign + MOD ) * tmp_matr[n-1][n] ) % MOD ;;
ans[t] = (res + MOD) % MOD ;
}
for(int i =1; i<= n -1; ++ i)
cout<<ans[i]<<" " ;
cout<<ans[n]<<endl;
}
return 0 ;
}