LUOGU P4783 【模板】矩阵求逆(高斯消元)

传送门

解题思路

  用高斯消元对矩阵求逆,设\(A*B=C\)\(C\)为单位矩阵,则\(B\)\(A\)的逆矩阵。做法是把\(B\)先设成单位矩阵,然后对\(A\)做高斯消元的过程,对\(B\)进行同样的操作,最后把\(A\)消成单位矩阵时,\(B\)就是其的逆矩阵。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>

using namespace std;
const int N=405;
const int MOD=1e9+7;

inline int rd(){
	int x=0,f=1; char ch=getchar();
	while(!isdigit(ch)) f=ch=='-'?0:1,ch=getchar();
	while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
	return f?x:-x;
}

int n,a[N][N],b[N][N];

inline int fast_pow(int x,int y){
	int ret=1;
	for(;y;y>>=1){
		if(y&1) ret=1ll*ret*x%MOD;
		x=1ll*x*x%MOD;
	}
	return ret;
}

bool gauss(){
	int tmp;
	for(int i=1;i<=n;++i){
		if(!a[i][i]){
			for(int j=i+1;j<=n;++j)
		 		if(a[j][i])	{
		 			for(int k=1;k<=n;k++) swap(a[j][k],a[i][k]),swap(b[j][k],b[i][k]);
		 			break;
		 		}
		}
		if(!a[i][i]) {puts("No Solution"); return 0;}
		tmp=fast_pow(a[i][i],MOD-2);
		for(int j=1;j<=n;++j)
			a[i][j]=1ll*a[i][j]*tmp%MOD,b[i][j]=1ll*b[i][j]*tmp%MOD;
		for(register int j=1;j<=n;++j)if(j!=i){
			tmp=a[j][i];
			for(register int k=1;k<=n;++k)
				a[j][k]=(a[j][k]-1ll*a[i][k]*tmp%MOD+MOD)%MOD,
				b[j][k]=(b[j][k]-1ll*b[i][k]*tmp%MOD+MOD)%MOD;
		}
	}
	return 1;
}

int main(){
	n=rd();
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++) a[i][j]=rd();
	for(int i=1;i<=n;i++) b[i][i]=1;
	if(gauss()){
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++)
				printf("%d ",b[i][j]);
			putchar('\n');		
		}	
	}
	return 0;
}
posted @ 2019-02-26 15:05  Monster_Qi  阅读(243)  评论(0编辑  收藏  举报