2021ICPC济南J.Determinant

题目:J.Determinant

题意:

给定一个矩阵,并且给出它的精确行列式的绝对值

判断行列式的正负

n<=100

思路:

随机一个大模数 P,令其不是给定行列式的因数。

计算行列式模 P 的值,与给定的数比较即可。

不难证明在 P 是奇数时行列式为正与为负的情况算出来的行列式总是不等。

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define sy system("pause")
const int mod=1e9+7;
int a[110][110];
int qpow(int a, int b) {
	int res = 1; a %= mod;
	while (b) {
		if (b & 1) res = (int)res * a % mod;
		a = (int)a * a % mod; b >>= 1;
	}
	return res;
}
  int n;
int inv(int x) { return qpow(x, mod - 2); } // 逆元
int check() { // 高斯消元 求 行列式
	int ans = 1;
	for(int i=1;i<=n;i++) {
		for(int j=i;j<=n;j++)
			if (a[j][i]) { // 不能让 p[i][i] = 0, 即对角线的部分不能为0
				for(int k=i;k<=n;k++) swap(a[i][k], a[j][k]);
				if (i != j) ans = -ans;//交换两行,行列式正负改变
				break;
			}

		// 用第 i 行去修改第 j 行
		// p[j][k] = p[j][k] - p[i][k] * p[j][i] / p[i][i];
		for (int j = i + 1, invf = inv(a[i][i]); j <= n; ++j) {
			int t = a[j][i] * invf % mod;
			for(int k=n;k>=i;k--) a[j][k] = ((a[j][k] - a[i][k] * t % mod) % mod + mod) % mod;
		}

		// 行列式的值就是化成上三角后主对角线的积乘上已经提取出来的数字
		ans = (ans * a[i][i] % mod + mod) % mod;
	}

	return ans;
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    string s;
    cin>>n>>s;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++) cin>>a[i][j];
    }
    int ans=s[0]-'0';
    for(int i=1;i<s.size();i++){
        ans=ans*10+(s[i]='0');
        ans%=mod;
    }
    if(ans==check()){
        cout<<"+"<<endl;
    }
    else cout<<"-"<<endl;
    sy;
    return 0;
}

posted @ 2021-11-19 23:09  Curry_BP  阅读(75)  评论(0)    收藏  举报