/**************************************************************
Problem: 4128
User: idy002
Language: C++
Result: Accepted
Time:4932 ms
Memory:4152 kb
****************************************************************/ #include <iostream>
#include <cstdio>
#include <cmath>
#include <map>
using namespace std; const int N = ; int n, Mod;
int inv[]; struct Matrix {
int v[N][N];
void unit() {
for( int i=; i<n; i++ )
for( int j=; j<n; j++ )
v[i][j] = (i==j);
}
void read() {
for( int i=; i<n; i++ )
for( int j=; j<n; j++ )
scanf( "%d", &v[i][j] );
}
}; int mpow( int a, int b ) {
int rt;
for( rt=; b; b>>=,a=(a*a)%Mod )
if( b& ) rt=(rt*a)%Mod;
return rt;
} Matrix operator*( const Matrix &a, const Matrix &b ) {
Matrix c;
for( int i=; i<n; i++ ) {
for( int j=; j<n; j++ ) {
c.v[i][j] = ;
for( int k=; k<n; k++ ) {
c.v[i][j] += a.v[i][k] * b.v[k][j] % Mod;
if( c.v[i][j]>=Mod ) c.v[i][j]-=Mod;
}
}
}
return c;
}
Matrix operator~( Matrix a ) {
Matrix b;
b.unit();
for( int i=,j; i<n; i++ ) {
for( int k=i; k<n; k++ )
if( a.v[k][i] ) {
j=k;
break;
}
if( i!=j ) {
for( int k=; k<n; k++ ) {
swap(a.v[i][k],a.v[j][k]);
swap(b.v[i][k],b.v[j][k]);
}
}
for( int j=i+; j<n; j++ ) {
int d = a.v[j][i]*inv[a.v[i][i]] % Mod;
for( int k=; k<n; k++ ) {
a.v[j][k] = (a.v[j][k] - a.v[i][k]*d) % Mod;
b.v[j][k] = (b.v[j][k] - b.v[i][k]*d) % Mod;
if( a.v[j][k]< ) a.v[j][k]+=Mod;
if( b.v[j][k]< ) b.v[j][k]+=Mod;
}
}
}
for( int i=n-; i>=; i-- ) {
int d = inv[a.v[i][i]];
for( int k=; k<n; k++ ) {
a.v[i][k] = a.v[i][k] * d % Mod;
b.v[i][k] = b.v[i][k] * d % Mod;
}
for( int j=i-; j>=; j-- ) {
d = a.v[j][i] * inv[a.v[i][i]] % Mod;
for( int k=; k<n; k++ ) {
a.v[j][k] = (a.v[j][k] - a.v[i][k]*d) % Mod;
b.v[j][k] = (b.v[j][k] - b.v[i][k]*d) % Mod;
if( a.v[j][k]< ) a.v[j][k] += Mod;
if( b.v[j][k]< ) b.v[j][k] += Mod;
}
}
}
return b;
}
bool operator<( const Matrix &a, const Matrix &b ) {
for( int i=; i<n; i++ )
for( int j=; j<n; j++ ) {
if( a.v[i][j] ^ b.v[i][j] )
return a.v[i][j] < b.v[i][j];
}
return false;
}
bool operator==( const Matrix &a, const Matrix &b ) {
for( int i=; i<n; i++ )
for( int j=; j<n; j++ )
if( a.v[i][j] ^ b.v[i][j] ) return false;
return true;
}
int ind( Matrix a, Matrix b ) {
map<Matrix,int> mp;
int m = int(sqrt(Mod))+;
Matrix base = a;
a.unit();
for( int i=; i<m; i++ ) {
if( a==b && i ) return i;
mp[a] = i;
a = a*base;
}
base = ~a;
a = b*base;
for( int i=m; ; i+=m,a=a*base )
if( mp.count(a) ) return i+mp[a];
} int main() {
scanf( "%d%d", &n, &Mod );
for( int i=; i<Mod; i++ )
inv[i] = mpow(i,Mod-);
Matrix a, b;
a.read();
b.read();
printf( "%d\n", ind(a,b) );
}

收获:

  1. 矩阵进行如下操作可以相当于用一个矩阵乘以它:

    将一行上的所有数乘以k

    将一行加到另一行上

    交换两行

  2. 求逆的过程

    如果要求矩阵A的逆矩阵A-1,先得到一个单位矩阵B,

    然后用上面1中的三种操作将A变成单位矩阵(不能变成单位矩阵则说明该矩阵行列式为0,即该矩阵不存在逆)

    将对A的所有操作同样地应用于B,最终B就是A-1

  3. 求逆的正确性

    我们对A进行了一系列变换,等同于用一个矩阵C乘以A使得 C*A = I

    即C是A的逆矩阵, 将同样的操作作用于B,得到的矩阵为 C*B = C*I = C

    即最终B的结果就是我们要求的逆

  4. 高斯消元的另一种理解

    A*X = B

    C*A*X = C*B

    完了

bzoj 4128 矩阵求逆的更多相关文章

  1. 【题解】Matrix BZOJ 4128 矩阵求逆 离散对数 大步小步算法

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4128 大水题一道 使用大步小步算法,把数字的运算换成矩阵的运算就好了 矩阵求逆?这么基础的线 ...

  2. BZOJ 4128: Matrix

    BZOJ 4128: Matrix 标签(空格分隔): OI BZOJ 大步小步 矩阵 费马小定理 Time Limit: 10 Sec Memory Limit: 128 MB Descriptio ...

  3. BZOJ 4128 Matrix BSGS+矩阵求逆

    题意:链接 方法: BSGS+矩阵求逆 解析: 这题就是把Ax=B(mod C)的A和B换成了矩阵. 然而别的地方并没有修改. 所以就涉及到矩阵的逆元这个问题. 矩阵的逆元怎么求呢? 先在原矩阵后接一 ...

  4. bzoj 4128: Matrix ——BSGS&&矩阵快速幂&&哈希

    题目 给定矩阵A, B和模数p,求最小的正整数x满足 A^x = B(mod p). 分析 与整数的离散对数类似,只不过普通乘法换乘了矩阵乘法. 由于矩阵的求逆麻烦,使用 $A^{km-t} = B( ...

  5. BZOJ 4128 Matrix ——BSGS

    矩阵的BSGS. 只需要哈希一下存起来就可以了. 也并不需要求逆. #include <map> #include <cmath> #include <cstdio> ...

  6. BZOJ 4128: Matrix (矩阵BSGS)

    类比整数的做法就行了 1A爽哉 #include<bits/stdc++.h> using namespace std; typedef long long LL; const int M ...

  7. 【BZOJ】4128: Matrix

    题解 学习一下矩阵求逆 就是我们考虑这个矩阵 \(AA^{-1} = I\) 我们相当于让\(A\)乘上一个矩阵,变成\(I\) 我们可以利用初等行变换(只能应用初等行变换,或只应用初等列变换) 分三 ...

  8. BZOJ 1444 [JSOI2009]有趣的游戏 (Trie图/AC自动机+矩阵求逆)

    题目大意:给你$N$个长度相等且互不相同的模式串,现在有一个字符串生成器会不断生成字符,其中每个字符出现的概率是$p_{i}/q_{i}$,当生成器生成的字符串包含了某个模式串,则拥有该模式串的玩家胜 ...

  9. BZOJ 3168 Luogu P4100 [HEOI2013]钙铁锌硒维生素 (矩阵求逆、二分图匹配)

    线性代数+图论好题. 题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=3168 (luogu) https://www.lu ...

随机推荐

  1. springboot系列十、springboot整合redis、多redis数据源配置

    一.简介 Redis 的数据库的整合在 java 里面提供的官方工具包:jedis,所以即便你现在使用的是 SpringBoot,那么也继续使用此开发包. 二.redidTemplate操作 在 Sp ...

  2. DES加密模式详解

    DES加密模式详解 http://www.cnblogs.com/Lawson/archive/2012/05/20/2510781.html http://www.blogjava.net/wayn ...

  3. python动态函数名的研究

    所谓动态函数名,就是使用时完全不知道是叫什么名字,可以由用户输入那种. 一般人习惯性会想到eval或exec, 但是众所周知,这样的写法不安全而且容易引起问题,而且不pythonic.而且使用时必须把 ...

  4. elk系统通过nginx添加对kibana的登录认证

    elk系统添加对kibana的登录认证 关于elk系统的安装配置可以参考:Centos6.5安装Logstash ELK stack 日志管理系统及使用详解 http://blog.csdn.net/ ...

  5. 在jsp页面,将小数转换为百分比

    <fmt:formatNumber type="number" value="${temp.illegalCount*100/temp.unitCount}&quo ...

  6. sklearn聚类模型:基于密度的DBSCAN;基于混合高斯模型的GMM

    1 sklearn聚类方法详解 2 对比不同聚类算法在不同数据集上的表现 3 用scikit-learn学习K-Means聚类 4 用scikit-learn学习DBSCAN聚类 (基于密度的聚类) ...

  7. 使用 IIS 在 Windows 上托管 ASP.NET Core

    参考微软文档: https://docs.microsoft.com/zh-cn/aspnet/core/host-and-deploy/iis/index?tabs=aspnetcore2x 将as ...

  8. JProfiler 入门教程

    推荐文章:JProfiler 入门教程 一.安装JProfiler 从http://www.ej-technologies.com/下载5.1.2并申请试用序列号 二.主要功能简介 1.内存剖析 Me ...

  9. js的闭包的一个示例说明

    js中 某个函数的内部函数在该函数执行结束后仍然可以访问这个函数中定义的变量,这称为闭包(Closure) 复制代码 代码如下: function outside() { var myVar = 1; ...

  10. js字符串截取为数组

    var str="hello,word,java,eclipse,jsp"; //字符串截取为数组 var strArr=str.split(","); for ...