bzoj 2107: Spoj2832 Find The Determinant III 辗转相除法

2107: Spoj2832 Find The Determinant III

Time Limit: 1 Sec  Memory Limit: 259 MB
Submit: 154  Solved: 46
[Submit][Status][Discuss]

Description

Problem code: DETER3

Given a NxN matrix A, find the Determinant of A % P.

给出一个尺寸为N×N的整数方阵A(N≤200),要求求出|A|%P的值(即A的行列式的值除以P的余数)。方阵中的数与P均为32位有符号类型可容纳的整数

Input

The first line of every test case contains two integers , representing N
(0 < N < 201) and P (0 < P < 1,000,000,001). The following N
lines each contain N integers, the j-th number in i-th line represents
A[i][j] (- 1,000,000,001 < A[i][j] < 1,000,000,001).

Output

For each test case, print a single line contains the answer.

Sample Input

3 4
-840419217 -895520213 -303215897
537496093 181887787 -957451145
-305184545 584351123 -257712188

Sample Output

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);
        }
}
时间: 2024-11-08 17:26:32

bzoj 2107: Spoj2832 Find The Determinant III 辗转相除法的相关文章

SPOJ - Find The Determinant III 计算矩阵的行列式答案 + 辗转相除法思想

SPOJ -Find The Determinant III 参考:https://blog.csdn.net/zhoufenqin/article/details/7779707 参考中还有几个关于行列式的性质. 题意: 计算矩阵的行列式答案 思路: 计算行列式的基本方法就是把矩阵化成上三角或下三角,然后观察对角线的元素,如果其中有一个元素为0则答案为0,否则行列式的值就是对角线上各个元素的乘积. #include <algorithm> #include <iterator>

SPOJ - DETER3:Find The Determinant III (求解行列式)

Find The Determinant III 题目链接:https://vjudge.net/problem/SPOJ-DETER3 Description: Given a NxN matrix A, find the Determinant of A % P. Input: Multiple test cases (the size of input file is about 3MB, all numbers in each matrix are generated randomly)

kuangbin带你飞 生成树专题 : 次小生成树; 最小树形图;生成树计数

第一个部分 前4题 次小生成树 算法:首先如果生成了最小生成树,那么这些树上的所有的边都进行标记.标记为树边. 接下来进行枚举,枚举任意一条不在MST上的边,如果加入这条边,那么肯定会在这棵树上形成一个环,如果还要维护处树的特点 那么就要在这个环上删去一条边,这样他还是树,删掉的边显然是这条链上权值最大边更可能形成次小生成树.那么就有2中方法可以做. 第一种PRIM在prim时候直接可以做出这个从I到J的链上权值最大的值MAX[i][j]; 同时可以用kruskal同样方式标记树边,然后DFS跑

bzoj 1803: Spoj1487 Query on a tree III(主席树)

题意 你被给定一棵带点权的n个点的有根数,点从1到n编号. 定义查询 query(x,k): 寻找以x为根的k大点的编号(从小到大排序第k个点) 假设没有两个相同的点权. 输入格式: 第一行为整数n,第二行为点权,接下来n-1行为树边,接下来一行为整数m,下面m行为两个整数x,k,代表query(x,k) 输出格式: m行,输出每次查询的结果. 题解 先一遍dfs,然后建个主席树,带上去直接跑一跑就好了 我忘了注意dfs序的位置和原来的编号……结果调了半天啥都调不出来…… 1 //minamot

bzoj 1493 暴力

我们可以枚举每个点,然后求出这个点到其余点最小消耗的代价,求出比t小的且距离最大的更新答案. /************************************************************** Problem: 1295 User: BLADEVIL Language: C++ Result: Accepted Time:4572 ms Memory:3944 kb ***************************************************

【BZOJ 3569】DZY Loves Chinese II 随机化+线性基

用到一个结论——[先建树,再给每个非树边一个权值,每个树边的权值为覆盖他的非树边的权值的异或和,然后如果给出的边存在一个非空子集异或和为0则不连通,否则连通](必须保证每条边的出现和消失只能由自己产生,即一个边不能由其他其他边异或得到,这就是我们随机化边权的原因) 证明:(前置性质:I.只割非树边一定不可以 II.非树边"藏"在树边里 III.非树边是在树上是简单路径 IV.对于一个连通块(只考虑树结构),"藏"在他周围树边里的非树边要么连接他与外界(只在他周围树边

bzoj 4283 魔法少女伊莉雅 - 最短路

题目传送门 需要高级权限的快速通道 题目大意 给定一个$n$个点$m$条边的带正权无向图.要求找一条路径满足: 它是一条简单路径 它是一条严格次短路 对于任何一条可能存在于最短路上的边,不能包含它的反向边. 不存在这条路径输出-1. 神题orz...orz....orz....良心的最短路性质题,涵盖了大部分最短路径树和最短路径图上的常用性质. 直觉是最短路上随意判一判就好了.然后全WA了,qwq.. 然后开始讲正题. 将$d\left(u, v \right )$记为点$u$到点$v$的最短路

F: 取数游戏III (思维+简单dp)

F: 取数游戏III 题目描述 小 C 刚学了辗转相除法,正不亦乐乎,这小 P 又出来捣乱,给小 C 留了个 难题. 给 N 个数,用 a1,a2-an来表示.现在小 P 让小 C 依次取数,第一个数可以 随意取.假使目前取得 aj,下一个数取ak(k>j),则ak必须满足gcd(aj,ak)≥L. 到底要取多少个数呢?自然是越多越好! 不用多说,这不仅是给小 C 的难题,也是给你的难题. 输入 第一行包含两个数N 和 L. 接下来一行,有 N 个数用空格隔开,依次是 a1,a2-an. 输出

BZOJ 1013: [JSOI2008]球形空间产生器sphere

二次联通门 : BZOJ 1013: [JSOI2008]球形空间产生器sphere /* BZOJ 1013: [JSOI2008]球形空间产生器sphere 高斯消元 QAQ SB的我也能终于能秒题了啊 设球心的坐标为(x,y,z...) 那么就可以列n+1个方程,化化式子高斯消元即可 */ #include <cstdio> #include <iostream> #include <cstring> #define rg register #define Max