洛谷4783 【模板】矩阵求逆

题目
这是一道矩阵求逆的模板题。
先了解一下什么叫矩阵求逆:
两个矩阵A,B,BA=I(I为单位矩阵)
其次我们要了解矩阵的三种初等变换:
1.交换某两行。
2.将某一行的所有元素乘上k(k≠0)。
3.将某一行的所有元素乘上k加到另一行去。
根据这三种初等变换便可以进行高斯消元。
现将矩阵消成上三角矩阵,再将上三角矩阵消成对角矩阵,最后消成单位矩阵。
在消的途中,对一个单位矩阵进行相同的操作,便能得到这个矩阵的逆矩阵。
原理:
矩阵的三种初等变换可以用矩阵乘以原矩阵来得到结果。
例如:1.交换两行。交换第一行和第二行,可以让原矩阵乘以一个
洛谷4783 【模板】矩阵求逆
这种类似单位矩阵的形式。
因此可知矩阵的初等变换可以写成矩阵乘法的形式。
那么矩阵A,经高斯消元后变为单位矩阵则可以表示为:
P1P2P3P4…Pn*A=I;即P1P2P3P4…Pn为矩阵A的逆元。
又因为一个单位向量乘以一个矩阵结果仍为这个矩阵,
因此对单位矩阵进行相同的操作后所得结果即为A的逆元。

#include<iostream>
#include<cstdio>
using namespace std;
typedef  long long ll;
const int maxn=410;
const ll p=1e9+7;
int n,m;
ll f[maxn][2*maxn];
ll r,ret;
ll kuaisumi(ll u,ll v)
{
	ret=1;
	while(v)
	{
		if(v%2) ret=ret*u%p;
		u=u*u%p;
		v/=2;
	}
	return ret;
}
int main()
{
	scanf("%d",&n);m=n*2;
	for(int i=1;i<=n;i++)
	{
	 for(int j=1;j<=n;j++)
	 	scanf("%lld",&f[i][j]);
	 	f[i][n+i]=1;
	 }
	for(int i=1;i<=n;i++)
	{
		for(int j=i;j<=n;j++)
		{
			if(f[j][i])
			{
				for(int k=1;k<=m;k++)
					swap(f[i][k],f[j][k]);
				break;
			}
		}
	if(!f[i][i])
	{
		printf("No Solution");return 0;
	}
	r=kuaisumi(f[i][i],p-2);
	for(int j=i;j<=m;j++)
		f[i][j]=f[i][j]*r%p;
	for(int j=1;j<=n;j++)
		if(j!=i)
		{
			r=f[j][i];
			for(int k=i;k<=m;k++)
			{
				f[j][k]=(f[j][k]-r*f[i][k]%p+p)%p;
			}
		}
  }
  for(int i=1;i<=n;i++,puts(" "))
  for(int j=n+1;j<=m;j++) printf("%lld ",f[i][j]);
  return 0;
}