初等变换求 |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)
我就是我,颜色不一样的烟火 --- geloutingyu