行列式的计算

 

行列式的计算要根据行列式的性质用高斯消元将他化为(上)下三角行列式

然后(上)下三角行列式的值为主对角线上的值相乘

因为:

根据行列式的定义,在所有排列中,只有a[]=( 1, 2, 3, ... )这一个排列满足 Mat[i][a[i]]都不为0

所以值就为Π(Mat[i][i])

如果在模意义下,那么高斯消元不能除,只能整除,用类似辗转相除法的方法消

 

Code:

//O(n^3logn)
#include
#include
#include
#include
#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;
}

 

你可能感兴趣的:(冲刺省选,数论)