行列式求值

行列式求值

给定一个行列式,求它的值,对任意模数取模。

分析

一个小技巧可以避免精度问题(或者说任意模数下逆元存在性问题),考虑使用类似求最大公约数地碾转相除法,在消除某行的主元时消到取余后的值,再交换两行重复上述步骤,直到消净(当然这种方法会牺牲对数级的复杂度)。

code

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=620;
int n,p,ans(1);
int a[N][N];
signed main(){
    cin>>n>>p;
    if(p==1) return puts("0"),0;
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j) cin>>a[i][j];
    assert(1);
    for(int i=1;i<=n;++i) if(!a[i][i]) return puts("0"),0;
    for(int i=1;i<=n;++i){
        for(int j=i;j<=n;++j){
            if(a[j][i]){
                for(int k=1;k<=n;++k) swap(a[j][k],a[i][k]);
                if(i^j) ans=ans*(p-1)%p;// 别忘了交换两行行列式的值取一次负
                break;
            }
        }
        for(int j=i+1;j<=n;++j){
            while(a[j][i]){
                if(a[i][i]>a[j][i]){
                    for(int k=1;k<=n;++k) swap(a[j][k],a[i][k]);
                    ans=ans*(p-1)%p;
                }
                int rate(a[j][i]/a[i][i]);
                for(int k=i;k<=n;++k){
                    a[j][k]=(a[j][k]%p+p-rate%p*a[i][k]%p)%p;
                }

            }
        }
    }
    for(int i=1;i<=n;++i) ans=(ans+p)%p*a[i][i]%p;
    cout<<(ans+p)%p<<endl;
}
posted @ 2026-01-21 20:38  Melting_Pot  阅读(8)  评论(0)    收藏  举报