初等变换求 |A| % Mod & A- % Mod & A* % Mod(模板)

 1 // |A| * A- = A* (伴随矩阵) = 逆矩阵 * 矩阵的值
 2 
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<ctime>
 8 #include<iostream>
 9 #include<algorithm>
10 using namespace std;
11 
12 const int MAXN = 205;
13 const int Mod = 1000000007;
14 int a[MAXN][MAXN], b[MAXN][MAXN];
15 
16 int fast_pow(int a, int k){
17     int res = 1;
18     while(k){
19         if(k & 1) res = 1LL * res * a % Mod;
20         a = 1LL * a * a % Mod;
21         k >>= 1;
22     }
23     return res;
24 }
25 
26 void solve(int n){
27     for(int i = 1; i <= n; i++){
28         for(int j = 1; j <= n; j++){
29             b[i][j] = (i==j);//初始 b 为单位矩阵
30         }
31     }
32 
33     int det = 1;
34     for(int i = 1; i <= n; i++){
35         int t = i;
36         for(int k = i; k <= n; k++){
37             if(a[k][i]) t = k;
38         }
39 
40         if(t != i) det *= -1;
41         for(int j = 1; j <= n; j++){
42             swap(a[i][j], a[t][j]);
43             swap(b[i][j], b[t][j]);
44         }
45 
46         det = 1LL * a[i][i] * det % Mod;
47         int inv = fast_pow(a[i][i], Mod-2); // a[i][i] 的逆元
48 
49         for(int j = 1; j <= n; j++){
50             a[i][j] = 1LL * inv * a[i][j] % Mod;
51             b[i][j] = 1LL * inv * b[i][j] % Mod;
52         }
53         for(int k = 1; k <= n; k++){
54             if(k == i) continue;
55             int tmp = a[k][i];
56             for(int j = 1; j <= n; j++){
57                 a[k][j] = (a[k][j] - 1LL * a[i][j] * tmp % Mod + Mod) % Mod;
58                 b[k][j] = (b[k][j] - 1LL * b[i][j] * tmp % Mod + Mod) % Mod;
59             }
60         }
61     }
62     //经过增广矩阵初等变换,此时 b 为 a 的逆矩阵
63     det = (det + Mod) % Mod;  //    |a| % Mod
64     for(int i = 1; i <= n; i++){
65         for(int j = 1; j<= n; j++){
66             b[i][j] = 1LL * det * b[i][j] % Mod;  //    将 b 由逆矩阵变成伴随矩阵
67         }
68     }
69 }
70 
71 int main(void){
72     int n;
73     while(scanf("%d",&n)!=EOF){
74         for(int i = 1; i <= n; i++)
75             for(int j = 1; j <= n; j++)
76                 scanf("%d", &a[i][j]);
77         solve(n);
78         for(int i = 1; i <= n; i++)
79             printf("%d%c",(i & 1 ? b[i][1] : (Mod - b[i][1]) % Mod), " \n" [i == n]);
80     }
81     return 0;
82 }

 

时间复杂度为 O(n^3)

posted @ 2017-07-15 12:49  geloutingyu  阅读(405)  评论(0编辑  收藏  举报