题目链接:https://www.luogu.org/problem/P4783
题意:求矩阵的逆。
思路:高斯消元法求矩阵的逆,n为400,卡常,我是开了O2优化才AC的。。
AC代码:
#include<cstdio>
#include<cctype>
#include<algorithm>
#define R register int
using namespace std;
const int maxn=405;
const int MOD=1e9+7;
int n;
struct Matrix{
int m[maxn][maxn];
void SWAP(int x,int y){ //交换两行
for(R i=1;i<=n;++i)
swap(m[x][i],m[y][i]);
}
void MUL(int x,int k){ //对一行乘上k
for(R i=1;i<=n;++i)
m[x][i]=(1LL*m[x][i]*k%MOD+MOD)%MOD;
}
void MULADD(int x,int y,int k){ //将第y行乘上k加到第x行上去
for(R i=1;i<=n;++i)
m[x][i]=((m[x][i]+1LL*m[y][i]*k%MOD)%MOD+MOD)%MOD;
}
}A,B;
int qpow(int a,int b){ //求逆元
int ret=1;
while(b){
if(b&1) ret=1LL*ret*a%MOD;
a=1LL*a*a%MOD;
b>>=1;
}
return ret;
}
void Invmatrix(){
for(R i=1;i<=n;++i){
if(!A.m[i][i]){
for(R j=i+1;j<=n;++j)
if(A.m[j][i]){
B.SWAP(i,j);
A.SWAP(i,j);
break;
}
}
if(!A.m[i][i]){ //没有逆矩阵
puts("No Solution");
return;
}
int tmp=qpow(A.m[i][i],MOD-2);
B.MUL(i,tmp);
A.MUL(i,tmp); //系数化为1
for(R j=i+1;j<=n;++j){ //消元
tmp=-A.m[j][i];
B.MULADD(j,i,tmp);
A.MULADD(j,i,tmp);
}
}
for(R i=n-1;i>=1;--i) //回带
for(R j=i+1;j<=n;++j){
int tmp=-A.m[i][j];
B.MULADD(i,j,tmp);
A.MULADD(i,j,tmp);
}
for(R i=1;i<=n;++i){
for(R j=1;j<=n;++j){
printf("%d",B.m[i][j]);
if(j!=n) printf(" ");
}
printf("\n");
}
}
int main(){
scanf("%d",&n);
for(R i=1;i<=n;++i)
for(R j=1;j<=n;++j)
scanf("%d",&A.m[i][j]);
for(R i=1;i<=n;++i){
for(R j=1;j<=n;++j)
B.m[i][j]=0;
B.m[i][i]=1;
}
Invmatrix();
return 0;
}