《P7112 【模板】行列式求值》

题目背景

模板题,无背景。

题目描述

给定一个 n 阶行列式 A,求 ∣A∣。结果对 p 取模。

输入格式

第一行两个正整数 n 和 p。

接下来共 n 行,第 i+1 行 n 个正整数,其中第 j 个表示 Ai,j​。

输出格式

输出 ∣A∣ 在模 p 意义下的最小自然数值。

输入输出样例

输入 #1复制

复制代码
2 998244353
1 4
1 5

输出 #1复制

复制代码
1

说明/提示

对于 100% 的数据,1≤n≤600,1≤ai,j​<109+7,1≤p≤109+7。

代码实现:

cpp 复制代码
#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<ctype.h>
namespace fasti{
	char buf[1<<15],*p1=buf,*p2=buf;
	#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<15,stdin),p1==p2)?EOF:*p1++)
	inline void read(int&x){
		char c=getc();
		for(;!isdigit(c);c=getc());
		for(x=0;isdigit(c);c=getc())x=(x<<1)+(x<<3)+(c^48);
	}
}
using fasti::read;

int mod;
int mat[600][600];
using std::swap;

inline int sub(int x, int y){return x<y?mod-(y-x):x-y;}

int main(){
    int n;
    read(n),read(mod);
    for(int i=0;i<n;++i)
        for(int j=0;j<n;++j)
            read(mat[i][j]),mat[i][j]%=mod;
    
    int res=1;
    for(int k=0;k<n;++k){
        int t;
        for(t=k;t<n;++t)
            if(mat[t][k])
                break;
        if(t==n)puts("0"),exit(0);
        if(t!=k)swap(mat[k],mat[t]),res=mod-res;
        
        for(int i=k+1;i<n;swap(mat[k],mat[i++]),res=mod-res)
            for(int div;mat[k][k];swap(mat[k],mat[i]),res=mod-res)
                for(int j=(div=mat[i][k]/mat[k][k],k);j<n;++j)
                    mat[i][j]=sub(mat[i][j],(long long)div*mat[k][j]%mod);
    }
    
    for(int i=0;i<n;++i)res=(long long)res*mat[i][i]%mod;
    printf("%d",res);
    return 0;
}
相关推荐
_OP_CHEN1 个月前
【算法基础篇】(三十八)数论之最大公约数与最小公倍数 —— 从原理到实战
蓝桥杯·数论·最大公约数·最小公倍数·欧几里得算法·acm/icpc·秦九韶算法
安红豆.1 年前
欧几里得算法--(密码学基础)
密码学·欧几里得算法