把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

luogu P4783 【模板】矩阵求逆

题面传送门
如果我们想求一个矩阵的逆,那么只要将一个矩阵变换成单位矩阵,然后操作矩阵的乘积就是答案。
然后这个过程可以用一个类似高斯消元的方法实现,时间复杂度\(O(n^3)\)
code:

#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define ll long long
#define db double
#define N 800
#define W (1<<20)
#define mod 1000000007
#define eps (1e-7)
#define U unsigned int
#define it iterator
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
using namespace std;
int n,m;ll A[N+5][N+5],now,pus;
I ll mpow(ll x,int y=mod-2){ll ans=1;while(y) (y&1)&&(ans=ans*x%mod),y>>=1,x=x*x%mod;return ans;}
I void swap(ll &x,ll &y){x^=y^=x^=y;}
I void calc(){
	re int i,j,h;for(i=1;i<=n;i++){
		for(now=0,j=i;j<=n;j++) A[j][i]&&(now=j);if(!now)printf("No Solution\n"),exit(0);if(now^i) for(j=1;j<=m;j++) swap(A[now][j],A[i][j]);
		now=mpow(A[i][i]);for(j=1;j<=m;j++) A[i][j]=A[i][j]*now%mod;
		for(j=1;j<=n;j++){
			if(i==j) continue;now=mod-A[j][i];for(h=1;h<=m;h++)A[j][h]=(A[j][h]+now*A[i][h])%mod; 
		}
	}
}
int main(){
// 	freopen("1.in","r",stdin);
	re int i,j;scanf("%d",&n);m=n<<1;for(i=1;i<=n;i++) for(A[i][i+n]=j=1;j<=n;j++) scanf("%lld",&A[i][j]);calc();for(i=1;i<=n;puts(""),i++)for(j=1;j<=n;j++) printf("%d ",A[i][j+n]);
}
posted @ 2021-07-23 21:44  275307894a  阅读(50)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end