行列式的计算要根据行列式的性质用高斯消元将他化为(上)下三角行列式
然后(上)下三角行列式的值为主对角线上的值相乘
因为:
根据行列式的定义,在所有排列中,只有a[]=( 1, 2, 3, ... )这一个排列满足 Mat[i][a[i]]都不为0
所以值就为Π(Mat[i][i])
如果在模意义下,那么高斯消元不能除,只能整除,用类似辗转相除法的方法消
Code:
//O(n^3logn)
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define maxn 205
using namespace std;
int n,p,a[maxn][maxn];
char ch;
int flag=0;
void get(int &res)
{
for(flag=1;!isdigit(ch=getchar());) if(ch=='-') flag=-1;
for(res=flag*(ch-'0');isdigit(ch=getchar());res=res*10+flag*(ch-'0'));
}
int det()
{
int ret=1;
for(int i=1;i<=n;i++)
{
for(int j=i+1;j<=n;j++)
while(a[j][i])
{
int t=a[i][i]/a[j][i];
for(int k=i;k<=n;k++)
{
a[i][k]=(a[i][k]-1ll*a[j][k]*t)%p;
swap(a[i][k],a[j][k]);
}
ret=-ret;
}
if(!a[i][i]) return 0;
ret=1ll*ret*a[i][i]%p;
}
return (ret+p)%p;
}
int main()
{
while(~scanf("%d%d",&n,&p))
{
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
get(a[i][j]);
printf("%d\n",det());
}
}
//O(n^3)
int det(int siz)
{
for(int i=1;i<=siz;i++)
for(int j=1;j<=siz;j++)
a[i][j]%=mod;
int ans = 1;
for(int i=1;i<=siz;i++)
{
for(int j=i+1;j<=siz;j++)
if(a[j][i])
{
int u = a[i][i] , v = a[j][i] , c[2][2] = {{1,0},{0,1}} , res, tim=0;
for(;v;)
{
res=u/v;
u = (u - 1ll*res * v) % mod;
c[0][0] = (c[0][0] - 1ll * c[1][0] * res) % mod , c[0][1] = (c[0][1] - 1ll * c[1][1] * res) % mod;
swap(u,v),swap(c[0][0],c[1][0]),swap(c[0][1],c[1][1]),swap(c[0][0],c[0][1]),swap(c[1][0],c[1][1]);
tim++;
}
if(tim & 1)
{
ans = -ans;
for(int k=i;k<=siz;k++) swap(a[i][k],a[j][k]);
}
for(int k=i;k<=siz;k++)
u = (1ll * a[i][k] * c[0][0] % mod + 1ll * a[j][k] * c[0][1]) % mod , v = (1ll * a[i][k] * c[1][0] % mod + 1ll * a[j][k] * c[1][1]) % mod,
a[i][k] = u , a[j][k] = v;
}
ans = 1ll * ans * a[i][i] % mod;
if(!ans) return 0;
}
return ans;
}