A:这是不是像上篇速战高斯消元一样都是水货?只用小学数学?
Q:如果你小学就会了这个,WOW,ORZ大佬
A:什么?这是不是很难?
Q:你学过线性代数不难
A:。。
常识:任何初等变化都可以在左边乘上一个矩阵表示
常识:增广矩阵
一步一步教你如何写出逆矩阵模板
先拿出草稿纸和笔
然后任意写一个矩阵
之后在矩阵旁边并排写上一个单位矩阵,并把它们当成整体,一起加减消元法
这之后就同高斯消元一样,消出一个梯形矩阵(左边原来的矩阵为上三角,若不为上三角,则无解)
然后在用加减消元法把它左边矩阵变成只有对角线的矩阵
最后把左边变成单位矩阵,右边那个就是逆矩阵
#include<cstdio>
#include<iostream>
#define ll long long
const int p=1e9+7;
using namespace std;
const int N=1005;
int n,a[N][N];
int ksm(ll a,int b)
{
ll ret=1;
while(b)
{
if(b&1) ret=ret*a%p;
a=a*a%p; b>>=1;
}
return (int)ret;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&a[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
a[i][n+j]=i==j;
for(int i=1;i<=n;i++)
{
if(a[i][i]==0)
{
bool f=0;
for(int j=i+1;j<=n;j++)
if(a[j][i]!=0)
{
for(int k=i;k<=n+n;k++)
swap(a[i][k],a[j][k]);
f=1;
break;
}
if(f==0)
{
puts("No Solution");
return 0;
}
}
for(int j=i+1;j<=n;j++)
if(a[j][i]!=0)
{
for(int k=i+1;k<=n+n;k++)
a[j][k]=(((ll)a[j][k]*a[i][i]-(ll)a[i][k]*a[j][i])%p+p)%p;
a[j][i]=0;
}
}
for(int i=n;i>=1;i--)
{
for(int j=i+1;j<=n;j++)
if(a[i][j]!=0)
{
for(int k=n+1;k<=n+n;k++)
a[i][k]=(((ll)a[i][k]-(ll)a[j][k]*a[i][j])%p+p)%p;
a[i][j]=0;
}
if(a[i][i]!=1)
{
int t=ksm((ll)a[i][i],p-2);
a[i][i]=1;
for(int j=n+1;j<=n+n;j++)
a[i][j]=(ll)a[i][j]*t%p;
}
}
for(int i=1;i<=n;i++)
for(int j=n+1;j<=n+n;j++)
printf("%d%c",a[i][j],j==n+n?'\n':' ');
return 0;
}