线代 可逆矩阵 行列式 伴随矩阵

#include<bits/stdc++.h>
#define ll long long
#define LL long long
using namespace std;
const int maxn=210;
const int mod=1e9+7;
ll a[maxn*2][maxn*2];
ll b[maxn*2][maxn*2];
int n;
int cet(){
    ll ans=1,s=0;
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            int x=i,y=j;
            while(a[y][i]){
                ll t=a[x][i]/a[y][i];
                for(int k=i;k<=n;k++){
                    a[x][k]=(a[x][k]-a[y][k]*t)%mod;
                }
                swap(x,y);
            }
            if(x!=i) {
                for(int k=1;k<=n;k++) swap(a[i][k],a[x][k]); s^=1;
            }
        }
        if(a[i][i]==0){
            return 0;
        }
        else ans=ans*a[i][i]%mod;
    }
    if(s) ans*=-1;
    if(ans<0) ans+=mod;
    return ans;
}
ll qpow(ll x,ll k){
    ll ans=1;
    while(k){
        if(k&1) ans=ans*x%mod;
        x=x*x%mod;
        k>>=1;
    }
    return ans%mod;
}

void guess(){
    for(int i=1,r;i<=n;++i){
        r=i;
        for(int j=i+1;j<=n;++j)
            if(a[j][i]>a[r][i]) r=j;
        if(r!=i)      swap(a[i],a[r]);
        int kk=qpow(a[i][i],mod-2);
        for(int k=1;k<=n;++k){
            if(k==i) continue;
            int p=a[k][i]*kk%mod;
            for(int j=i;j<=(n<<1);++j)   a[k][j]=((a[k][j]-p*a[i][j])%mod+mod)%mod;
        }
        for(int j=1;j<=(n<<1);++j) a[i][j]=(a[i][j]*kk%mod);
    }
}

int main(){
    while(scanf("%d",&n)!=EOF){
        for(int i=1;i<=n-1;i++){
            for(int j=1;j<=n;j++){
                scanf("%lld",&a[i][j]);
            }
        }
        for(int i=1;i<=n;i++) a[n][i]=1;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                b[i][j]=a[i][j];
            }
            b[i][i+n]=1;
        }

        int k=cet();// cout<<k<<endl;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=2*n;j++){
                a[i][j]=b[i][j];
            }
        }
        guess();
        for(int i=1;i<=n;i++){
            if(i!=1) printf(" ");
            int w=0;
            if((i+n)%2==1) w=-1;
            else           w=1;
            printf("%lld",(a[i][n+n]*k*w%mod+mod)%mod);
        }
        printf("\n");
        for(int i=1;i<=2*n;i++)
            for(int j=1;j<=2*n;j++)
                a[i][j]=b[i][j]=0;
    }
}

猜你喜欢

转载自www.cnblogs.com/Andromeda-Galaxy/p/11624614.html