求逆矩阵模板
高斯消元可以做到\(O(n^6)\)吧。
有一种很巧妙的做法:
我们知道:\(A*A^{-1}=E\),要求\(A^{-1}\)
设一个\(P=E\),那么一开始满足\(A*P=A\)
假设我们对右边的\(A\)做高斯消元,把它消成\(E\)。
我们知道高斯消元每次的操作相当于右乘一个矩阵\(B\)。
\((A*P)*B=A*B\)
\(A*(P*B)=A*B\)
也就是说,在右边的\(A\)进行消元时,对左边的\(P\)进行完全一样的操作。
那么最后就会得到\(A*P=E\)
Code:
#include<bits/stdc++.h>
#define fo(i, x, y) for(int i = x, _b = y; i <= _b; i ++)
#define ff(i, x, y) for(int i = x, _b = y; i < _b; i ++)
#define fd(i, x, y) for(int i = x, _b = y; i >= _b; i --)
#define ll long long
#define pp printf
#define hh pp("\n")
using namespace std;
const int mo = 1e9 + 7;
ll ksm(ll x, ll y) {
ll s = 1;
for(; y; y /= 2, x = x * x % mo)
if(y & 1) s = s * x % mo;
return s;
}
const int N = 105;
int n;
ll a[N][N], d[N][N], b[N][N], c[N][N];
int main() {
n = 10;
fo(i, 1, n) fo(j, 1, n)
a[i][j] = rand() % 10;
fo(i, 1, n) fo(j, 1, n) d[i][j] = a[i][j];
fo(i, 1, n) b[i][i] = 1;
fo(i, 1, n) {
int u = -1;
fo(j, i, n) if(a[j][i]) {
u = j; break;
}
if(u == -1) break;
fo(j, 1, n) swap(a[i][j], a[u][j]), swap(b[i][j], b[u][j]);
ll v = ksm(a[i][i], mo - 2);
fo(j, 1, n) a[i][j] = a[i][j] * v % mo, b[i][j] = b[i][j] * v % mo;
fo(j, 1, n) if(i != j && a[j][i]) {
ll v = -a[j][i];
fo(k, 1, n) a[j][k] = (a[i][k] * v + a[j][k]) % mo, b[j][k] = (b[i][k] * v + b[j][k]) % mo;
}
}
fo(k, 1, n) fo(i, 1, n) fo(j, 1, n)
c[i][j] = (c[i][j] + d[i][k] * b[k][j]) % mo;
fo(i, 1, n) {
fo(j, 1, n) pp("%lld ", c[i][j]);
hh;
}
}
转载注意标注出处:
转自Cold_Chair的博客+原博客地址