1. 程式人生 > >初等變換求 |A| % Mod & A- % Mod & A* % Mod(模板)

初等變換求 |A| % Mod & A- % Mod & A* % Mod(模板)

while tin continue amp 單位 color mod bsp 矩陣

 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)

初等變換求 |A| % Mod & A- % Mod & A* % Mod(模板)