把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

luogu P7112 【模板】行列式求值

行列式大概是对于一个矩阵让你算这么一个数:\(\sum\limits_{p}{(-1)^{τ(p)}\prod\limits_{i=1}^{n}{a_{i,p_i}}}\)
直接根据定义算这个东西是\(O(n!)\)的显然不行。
我们考虑如果一个行列式的下三角是空,那么它的权值就是对角线乘积。
所以我们要用一个类高斯消元的方法让它下三角为空。
因为行列式两行相减倍数不变,交换两行值取反所以这个很好做。
然后注意因为全部是整数运算,所以不能出现实数,得用一个辗转相除法。那个东西是\(O(n^2(n+logp))\)的。
code:

#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define ll long long
#define db double
#define N 1000
#define M 5000
#define mod 1000000000
#define eps (1e-7)
#define U unsigned int
#define it iterator
#define Gc() getchar() 
#define Me(x,y) memset(x,y,sizeof(x))
using namespace std;
int n,m,p;ll A[N+5][N+5],ans,f=1,now;
I void swap(ll &x,ll &y){x^=y^=x^=y;}
int main(){
	freopen("1.in","r",stdin);
	re int i,j,h;scanf("%d%d",&n,&p);for(i=1;i<=n;i++) for(j=1;j<=n;j++) scanf("%lld",&A[i][j]),A[i][j]%=p;
	for(i=1;i<=n;i++){
		for(j=i+1;j<=n;j++){
			while(A[j][i]){
				now=p-A[i][i]/A[j][i];for(h=i;h<=n;h++) A[i][h]=(A[j][h]*now+A[i][h])%p;
				for(h=i;h<=n;h++) swap(A[i][h],A[j][h]);f*=-1;
			}
		}
	}
	for(i=1;i<=n;i++) f=f*A[i][i]%p;printf("%lld\n",(f+p)%p);
}
posted @ 2021-07-17 06:32  275307894a  阅读(181)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end