题目链接
题目思路
先介绍行列式的变化对于行列式值的改变
1 如果交换矩阵的两行,则行列式的符号要取反
2 如果用某数t乘以矩阵的一行,则行列式等于原行列式的t倍
3 三角阵的行列式等于对角线元素乘积
4 从矩阵的行k减去行i的l倍,行列式不会改变,即消元过程不改变行列式
根据上面的式子用高斯消元化简即可
注意这里不需要求逆元,由于行列的相互加减不会影响行列式的值
所以使用辗转相除法
代码
#include<bits/stdc++.h>
#define fi first
#define se second
#define debug cout<<"I AM HERE"<<endl;
using namespace std;
typedef long long ll;
const int maxn=600+5,inf=0x3f3f3f3f4;
const double eps=1e-6;
const ll INF=0x3f3f3f3f3f3f3f3f;
int n,mod;
ll a[maxn][maxn];
ll gs(int n){
ll ans=1;
bool flag=1;
for(int i=1,pos;i<=n;i++){
for(pos=i;pos<=n;pos++){
if(a[pos][i]){
break;
}
}
if(pos==n+1){
return 0;
}
if(pos!=i){
flag^=1;
swap(a[pos],a[i]);
}
for(int j=i+1;j<=n;j++){
if(a[i][i]>a[j][i]){
swap(a[i],a[j]);
flag^=1;
}
while(a[j][i]){
swap(a[i],a[j]);
flag^=1;
ll p=a[j][i]/a[i][i];
for(int k=i;k<=n;k++){
a[j][k]=(a[j][k]+(mod-p)*a[i][k])%mod;
}
}
}
ans=ans*a[i][i]%mod;
}
if(!flag){
ans=(-ans+mod)%mod;
}
return ans;
}
signed main(){
scanf("%d%d",&n,&mod);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
scanf("%lld",&a[i][j]);
}
}
ll ans=gs(n);
printf("%lld\n",ans);
return 0;
}