您的位置:首页 > 其它

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

2018-09-09 22:08 447 查看

  对矩阵进行高斯消元直至消为单位矩阵,并在另一个单位矩阵上对其做同样的操作即可。

  模意义下的高斯消元可以直接计算系数来避免整行的辗转相除。

  还不知道有什么用。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
#define P 1000000007
#define N 410
int n,a

,b

;
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int ksm(int a,int k)
{
if (k==0) return 1;
int tmp=ksm(a,k>>1);
if (k&1) return 1ll*tmp*tmp%P*a%P;
else return 1ll*tmp*tmp%P;
}
int inv(int a){return ksm(a,P-2);}
void gauss()
{
for (int i=1;i<n;i++)
{
if (!a[i][i])
for (int j=i+1;j<=n;j++)
if (a[j][i]) {swap(a[i],a[j]),swap(b[i],b[j]);break;}
for (int j=i+1;j<=n;j++)
if (a[j][i])
{
int x=a[j][i]/gcd(a[i][i],a[j][i]),y=a[i][i]/gcd(a[i][i],a[j][i]);
for (int k=1;k<=n;k++)
a[j][k]=(1ll*a[j][k]*y%P-1ll*a[i][k]*x%P+P)%P,
b[j][k]=(1ll*b[j][k]*y%P-1ll*b[i][k]*x%P+P)%P;
}
}
if (a

)
{
for (int i=1;i<=n;i++)
b
[i]=1ll*b
[i]*inv(a

)%P;
a

=1;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
a[i][j]=read(),b[i][j]=(i==j);
gauss();
for (int i=1;i<=n;i++) if (a[i][i]==0) {cout<<"No Solution";return 0;}
for (int i=n;i>1;i--)
for (int j=i-1;j>=1;j--)
if (a[j][i])
{
int x=a[j][i]/gcd(a[i][i],a[j][i]),y=a[i][i]/gcd(a[i][i],a[j][i]);
for (int k=1;k<=n;k++)
a[j][k]=(1ll*a[j][k]*y%P-1ll*a[i][k]*x%P+P)%P,
b[j][k]=(1ll*b[j][k]*y%P-1ll*b[i][k]*x%P+P)%P;
}
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
b[i][j]=1ll*b[i][j]*inv(a[i][i])%P;
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
printf("%d ",b[i][j]);
printf("\n");
}
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: