标签:
2
其实一说算法名称大概都会做了吧。高斯消元的除法本质上等效与辗转相处法,而辗转相处不存在精度误差。我们为了把两行之一消掉,通过辗转相除大行减小行变成类似子问题。
最开始尝试用java的BigDecimal,结果发现精度和时间是不可同时满足的。
矩阵行列式求法可几何理解,向量(基底)可以互相加减,而不影响体积,然而基底互换,有向体积取反。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; #define MAXN 210 typedef long long qword; qword mat[MAXN][MAXN]; int main() { //freopen("input.txt","r",stdin); int n,m,x,y,z; int mod; while (~scanf("%d%d",&n,&mod)) { for (int i=1;i<=n;i++) { for (int j=1;j<=n;j++) { scanf("%lld",&mat[i][j]); mat[i][j]%=mod; } } int rev=1; for (int i=1;i<=n;i++) { x=-1; for (int j=i;j<=n;j++) { if (mat[j][i]) { x=j; break; } } if (x==-1)break; if (x!=i) { for (int j=1;j<=n;j++) swap(mat[x][j],mat[i][j]); rev=-rev; } if (!mat[i][i])break; for (int j=i+1;j<=n;j++) { while (mat[i][i]) { qword t=mat[j][i]/mat[i][i]; for (int k=1;k<=n;k++) mat[j][k]=(mat[j][k]-mat[i][k]*t)%mod; for (int k=1;k<=n;k++) swap(mat[j][k],mat[i][k]); rev=-rev; } for (int k=1;k<=n;k++) swap(mat[j][k],mat[i][k]); rev=-rev; } } qword ans=1; for (int i=1;i<=n;i++) ans=ans*mat[i][i]%mod; ans=(ans*rev+mod)%mod; printf("%lld\n",ans); } }
bzoj 2107: Spoj2832 Find The Determinant III 辗转相除法
标签:
原文地址:http://www.cnblogs.com/mhy12345/p/4445781.html