湘潭CCPC A题

来源:互联网 发布:mac万得股票机构 编辑:程序博客网 时间:2024/05/29 09:56

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 longconst 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 , 1LONG 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 ;}
原创粉丝点击