【题解】Matrix BZOJ 4128 矩阵求逆 离散对数 大步小步算法
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4128
大水题一道
使用大步小步算法,把数字的运算换成矩阵的运算就好了
矩阵求逆?这么基础的线代算法我也不想多说,还是自行百度吧
需要注意的是矩阵没有交换律,所以在计算$B\cdot A^{-m}$的时候不要把顺序搞混
代码:
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <map>
#include <cmath> using namespace std;
const int MAXN = ; int n, p; struct Matrix {
int a[MAXN][MAXN];
int *operator[]( int idx ) {
return a[idx];
}
const int *operator[]( int idx ) const {
return a[idx];
}
bool operator<( const Matrix &rhs ) const { // 用于map
for( int i = ; i < n; ++i )
for( int j = ; j < n; ++j )
if( a[i][j] < rhs[i][j] ) return true;
else if( a[i][j] > rhs[i][j] ) return false;
return false;
}
void unit() { // 填成n阶单位矩阵
memset( a, , sizeof(a) );
for( int i = ; i < n; ++i ) a[i][i] = ;
}
void clear() { // 填成全0
memset( a, , sizeof(a) );
}
};
Matrix A, B; // 题目中给定的A,B矩阵 int pow_mod( int a, int b ) { // 整数快速幂
int ans = ;
while(b) {
if( b& ) ans = ans * a % p;
a = a * a % p;
b >>= ;
}
return ans;
}
int inv( int a ) { // 整数求逆
return pow_mod(a,p-);
}
void input_matrix( Matrix &A ) {
for( int i = ; i < n; ++i )
for( int j = ; j < n; ++j ) {
scanf( "%d", &A[i][j] );
A[i][j] %= p;
}
}
void mul( const Matrix &A, const Matrix &B, Matrix &C ) { // 矩阵乘法,结果存入C
Matrix tmp; tmp.clear();
for( int i = ; i < n; ++i )
for( int j = ; j < n; ++j )
for( int k = ; k < n; ++k )
tmp[i][j] = (tmp[i][j] + A[i][k] * B[k][j] % p) % p;
C = tmp;
}
void gauss_jordan( int A[MAXN][MAXN<<] ) { // 高斯约当消元求逆
for( int i = ; i < n; ++i ) {
int r;
for( r = i; r < n; ++r )
if( A[r][i] ) break;
if( r != i )
for( int j = i; j < (n<<); ++j )
swap( A[r][j], A[i][j] );
int iv = inv( A[i][i] );
for( int j = i; j < (n<<); ++j )
A[i][j] = A[i][j] * iv % p;
for( int j = ; j < n; ++j )
if( j != i && A[j][i] ) {
int tmp = (p - A[j][i]) % p;
for( int k = i; k < (n<<); ++k )
A[j][k] = (A[j][k] + A[i][k] * tmp % p) % p;
}
}
}
void inv( const Matrix &A, Matrix &B ) { // 矩阵求逆,结果存入B
int tmp[MAXN][MAXN<<] = {};
for( int i = ; i < n; ++i )
for( int j = ; j < n; ++j )
tmp[i][j] = A[i][j];
for( int i = ; i < n; ++i ) tmp[i][i+n] = ;
gauss_jordan(tmp);
for( int i = ; i < n; ++i )
for( int j = ; j < n; ++j )
B[i][j] = tmp[i][j+n];
} map<Matrix,int> mp;
int bsgs( Matrix A, Matrix B ) { // 大步小步算法
int m = sqrt(p)+;
Matrix E; E.unit();
for( int i = ; i < m; ++i ) {
if( !mp.count(E) ) mp[E] = i;
mul(E,A,E);
}
inv(E,E);
for( int i = ; i < p; i += m ) {
if( mp.count(B) ) return i + mp[B];
mul(B,E,B); // 注意矩阵乘法顺序
}
return -;
} int main() {
scanf( "%d%d", &n, &p );
input_matrix(A), input_matrix(B);
printf( "%d\n", bsgs(A,B) );
return ;
}
【题解】Matrix BZOJ 4128 矩阵求逆 离散对数 大步小步算法的更多相关文章
- 离散对数&&大步小步算法及扩展
bsgs algorithm ax≡b(mod n) 大步小步算法,这个算法有一定的局限性,只有当gcd(a,m)=1时才可以用 原理 此处讨论n为素数的时候. ax≡b(mod n)(n为素数) 由 ...
- UVA 11916 Emoogle Grid 离散对数 大步小步算法
LRJ白书上的题 #include <stdio.h> #include <iostream> #include <vector> #include <mat ...
- 离散对数及其拓展 大步小步算法 BSGS
离散对数及其拓展 离散对数是在群Zp∗Z_{p}^{*}Zp∗而言的,其中ppp是素数.即在在群Zp∗Z_{p}^{*}Zp∗内,aaa是生成元,求关于xxx的方程ax=ba^x=bax=b的解, ...
- [模板]大步小步算法——BSGS算法
大步小步算法用于解决:已知A, B, C,求X使得 A^x = B (mod C) 成立. 我们令x = im - j | m = ceil(sqrt(C)), i = [1, m], j = [0, ...
- 大步小步算法模板题, poj2417
大步小步模板 (hash稍微有一点麻烦, poj不支持C++11略坑) #include <iostream> #include <vector> #include <c ...
- bzoj 4128 矩阵求逆
/************************************************************** Problem: 4128 User: idy002 Language: ...
- BSGS-Junior·大步小步算法
本文原载于:http://www.orchidany.cf/2019/02/06/BSGS-junior/#more \(\rm{0x01}\) \(\mathcal{Preface}\) \(\rm ...
- [BSGS]大步小步算法
问题 BSGS被用于求解离散对数,即同余方程: \[ A^x\equiv B\pmod{P} \] 求\(x\)的最小非负整数解. 保证\(A\perp P\)(互质). 分析 首先,我们根据费马小定 ...
- BSGS算法(大步小步算法)
计算\(y^x ≡ z \ mod\ p\) 中 \(x\) 的解. 这个模板是最小化了\(x\) , 无解输出\(No \ Solution!\) map<ll,ll>data; ll ...
随机推荐
- 深入理解java虚拟机学习笔记(二)
第三章 垃圾收集器与内存分配策略 概述 程序计数器.虚拟机栈.本地方法栈3个区随线程而生,随线程而灭.因此大体上可认为这几个区域的内存分配和回收都具备确定性.在方法/线程结束时,内存自然就跟着回收 ...
- CSP201709-1:打酱油
引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...
- (转)CGMA - Organic World Building in UE4: week 6
原文:丢失,这篇是艺术家博客上发现的,小道整理笔记中,临时放于效果案例目录. In this week we focused on creating the grass and flora t ...
- [Clr via C#读书笔记]Cp3共享程序集和强命名程
Cp3共享程序集和强命名程序集 私有方式部署+全局方式部署:弱命名程序集+强命名程序集 强命名程序集使用发布者的公钥私钥进行签名,唯一标识发布者. 共享dll被全部复制到System32中 强命名程序 ...
- 2018(容斥定理 HDU6286)
2018 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 2019寒假训练营寒假作业(三) MOOC的网络空间安全概论笔记部分
目录 第五章 网络攻防技术 5.1:网络信息收集技术--网络踩点 信息收集的必要性及内容 网络信息收集技术 网络踩点(Footprinting) 网络踩点常用手段 5.2:网络信息收集技术 --网络扫 ...
- 团队作业7——第二次项目冲刺(Beta版本)-第二篇
1.工作分工: 团队成员 分工 郭达22120 项目整合,后台代码 刘德培44060 数据库模块 石浩洋22061 前台界面优化 曾繁钦22056 前台界面优化.测试 孙斌22030 后台代码 2.燃 ...
- PAT 1035 插入与归并
https://pintia.cn/problem-sets/994805260223102976/problems/994805286714327040 据维基百科的定义: 插入排序是迭代算法,逐一 ...
- Zabbix监控配置
Zabbix在线文档 https://www.zabbix.com/documentation/4.0/zh/manual/config/hosts 1.我们启动服务后,我们看到了端口都正在监听,但是 ...
- 创建 cordova 项目
1. 安装 node.js 2.安装 cordova : npm install -g cordova 3.创建 安卓项目: cordova create <项目路径> <包名&g ...