对矩阵进行高斯消元直至消为单位矩阵,并在另一个单位矩阵上对其做同样的操作即可。
模意义下的高斯消元可以直接计算系数来避免整行的辗转相除。
还不知道有什么用。
#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[N][N],b[N][N]; 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[n][n]) { for (int i=1;i<=n;i++) b[n][i]=1ll*b[n][i]*inv(a[n][n])%P; a[n][n]=1; } } int main() { #ifndef ONLINE_JUDGE freopen("a.in","r",stdin); freopen("a.out","w",stdout); const char LL[]="%I64d "; #else const char LL[]="%lld "; #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(" "); } return 0; }