BZOJ 4128 Matrix BSGS+矩阵求逆
题意:链接
方法: BSGS+矩阵求逆
解析:
这题就是把Ax=B(mod C)的A和B换成了矩阵。
然而别的地方并没有修改。
所以就涉及到矩阵的逆元这个问题。
矩阵的逆元怎么求呢?
先在原矩阵后接一个单位矩阵,最好还是设右对角线
先把原矩阵进行高斯消元
且消成严格右对角线的单位矩阵的形式。
然后在消元的同一时候把单位矩阵的部分一并计算。最后单位矩阵就变成了它的逆矩阵。
这道题保证矩阵有逆
然而没有逆矩阵的情况就是高斯消元搞不成。
所以推断应该也好推断。
另外,刚刚实測本题数据。关于将矩阵的hash,直接取右下角的值即可了。太弱了数据
代码:
#include <map>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 75
#define M 140345
#define base 0
using namespace std;
int n,p;
struct Matrix
{
int map[N][N];
}A,B,ret;
struct node
{
int from,to,next;
int val;
}edge[M+10];
int cnt,head[M+10];
void init()
{
memset(head,-1,sizeof(head));
cnt=1;
}
void edgeadd(int from,int to,int val)
{
edge[cnt].from=from,edge[cnt].to=to,edge[cnt].val=val;
edge[cnt].next=head[from];
head[from]=cnt++;
}
Matrix mul(Matrix a,Matrix b)
{
memset(ret.map,0,sizeof(ret.map));
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
ret.map[i][j]=(ret.map[i][j]+a.map[i][k]*b.map[k][j])%p;
return ret;
}
int quick_my(int x,int y)
{
int ret=1;
while(y)
{
if(y&1)ret=(ret*x)%p;
x=(x*x)%p;
y>>=1;
}
return ret;
}
int hash(Matrix x)
{
return x.map[n][n];
}
Matrix get_inv(Matrix x)
{
memset(ret.map,0,sizeof(ret.map));
for(int i=1;i<=n;i++)ret.map[i][i]=1;
for(int i=1;i<=n;i++)
{
int chose=-1;
for(int j=i;j<=n;j++)
if(x.map[j][i]!=0){chose=j;break;}
//if(chose==-1)
// return -1
//无解我脑补应该是这样吧。
for(int j=1;j<=n;j++)
swap(x.map[i][j],x.map[chose][j]),swap(ret.map[i][j],ret.map[chose][j]);
int inv=quick_my(x.map[i][i],p-2);
for(int j=1;j<=n;j++)
{
x.map[i][j]=x.map[i][j]*inv%p;
ret.map[i][j]=ret.map[i][j]*inv%p;
}
for(int j=1;j<=n;j++)
{
if(i==j)continue;
int pre=x.map[j][i];//一定要提前记录不然肯定会影响答案。由于这个值被改变=-=我也是脑残了。
for(int k=1;k<=n;k++)
{
x.map[j][k]=((x.map[j][k]-pre*x.map[i][k])%p+p)%p;
ret.map[j][k]=((ret.map[j][k]-pre*ret.map[i][k])%p+p)%p;
}
}
}
return ret;
}
int BSGS(Matrix A,Matrix B,int C)
{
init();
int m=(int)ceil(sqrt(C));
Matrix tmp;
memset(tmp.map,0,sizeof(tmp.map));
for(int i=1;i<=n;i++)tmp.map[i][i]=1;
for(int i=0;i<m;i++)
{
int hashtmp=hash(tmp);
int flag=1;
for(int j=head[hashtmp%M];j!=-1;j=edge[j].next)
if(edge[j].val==hashtmp){flag=0;break;}
if(flag)edgeadd(hashtmp%M,i,hashtmp);
tmp=mul(tmp,A);
}
Matrix inv=get_inv(tmp);
for(int i=0;i<=m;i++)
{
int hashB=hash(B);
for(int j=head[hashB%M];j!=-1;j=edge[j].next)
if(edge[j].val==hashB)return i*m+edge[j].to;
B=mul(B,inv);
}
return -1;
}
int main()
{
scanf("%d%d",&n,&p);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&A.map[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&B.map[i][j]);
printf("%d\n",BSGS(A,B,p));
}
BZOJ 4128 Matrix BSGS+矩阵求逆的更多相关文章
- bzoj 4128: Matrix ——BSGS&&矩阵快速幂&&哈希
题目 给定矩阵A, B和模数p,求最小的正整数x满足 A^x = B(mod p). 分析 与整数的离散对数类似,只不过普通乘法换乘了矩阵乘法. 由于矩阵的求逆麻烦,使用 $A^{km-t} = B( ...
- BZOJ 4128 Matrix ——BSGS
矩阵的BSGS. 只需要哈希一下存起来就可以了. 也并不需要求逆. #include <map> #include <cmath> #include <cstdio> ...
- BZOJ 4128: Matrix
BZOJ 4128: Matrix 标签(空格分隔): OI BZOJ 大步小步 矩阵 费马小定理 Time Limit: 10 Sec Memory Limit: 128 MB Descriptio ...
- BZOJ 4128: Matrix (矩阵BSGS)
类比整数的做法就行了 1A爽哉 #include<bits/stdc++.h> using namespace std; typedef long long LL; const int M ...
- 【题解】Matrix BZOJ 4128 矩阵求逆 离散对数 大步小步算法
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=4128 大水题一道 使用大步小步算法,把数字的运算换成矩阵的运算就好了 矩阵求逆?这么基础的线 ...
- 【BZOJ】4128: Matrix
题解 学习一下矩阵求逆 就是我们考虑这个矩阵 \(AA^{-1} = I\) 我们相当于让\(A\)乘上一个矩阵,变成\(I\) 我们可以利用初等行变换(只能应用初等行变换,或只应用初等列变换) 分三 ...
- bzoj 4128 矩阵求逆
/************************************************************** Problem: 4128 User: idy002 Language: ...
- BZOJ4128: Matrix(BSGS 矩阵乘法)
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 813 Solved: 442[Submit][Status][Discuss] Descriptio ...
- 【BZOJ4128】Matrix BSGS+hash
[BZOJ4128]Matrix Description 给定矩阵A,B和模数p,求最小的x满足 A^x = B (mod p) Input 第一行两个整数n和p,表示矩阵的阶和模数,接下来一个n * ...
随机推荐
- .net学习笔记--设计模式
设计模式都有哪些? 按照GOF提出,23种,按照目的分为:创建型(creational).结构性(structural).行为型(behavioral). 一.创建型: 1.Singleton 单例模 ...
- PAT 甲级 1047 Student List for Course
https://pintia.cn/problem-sets/994805342720868352/problems/994805433955368960 Zhejiang University ha ...
- input[type="radio"]自定义样式
input为radio时,虽然会有默认选中的样式,但是并不符合大多数项目的需求,我们的目标是可以随心所欲自定义它的样式.怎么做呢?其实很简单,只要抓住3点.分别是1.label 2.隐藏自带样式 3. ...
- shell总结
1. shell脚本的变量赋值 变量赋值语句中的等号左右不能有空格 即 a = 4 //错误 a=4 //正确 2. shell脚步的执行需要权限 chmod +x shell.sh ./shel ...
- py2exe error: [Errno 2] No such file or directory: 'MSVCP90.dll'
使用 python setup.py py2exe 打包时出现 py2exe error: [Errno 2] No such file or directory: 'MSVCP90.dll' 解决方 ...
- 【转】Nodejs学习笔记(一)--- 简介及安装Node.js开发环境
目录 学习资料 简介 安装Node.js npm简介 开发工具 Sublime Node.js开发环境配置 扩展:安装多版本管理器 学习资料 1.深入浅出Node.js http://www.info ...
- 在本地(自己电脑上)部署了tomcat服务器,真机测试遇到的问题
开始的时候自己就是给app搭建了一个小的框架,只有一个界面发送了网络请求,部署的tomcat,数据成功请求,得到了数据. 后来随着联网请求的增多,突然发现联网请求一直失败.自己dubug了最开始的第一 ...
- AC日记——Car的旅行路线 洛谷 P1027
Car的旅行路线 思路: 这题不难,就是有点恶心: 而且,请认真读题目(就是题目卡死劳资): 来,上代码: #include <cmath> #include <cstdio> ...
- C#根据经纬度获取物理地址
废话不多说,直接上代码: 1.首先新建几个类,定义一些属性: public class BaiDuGeoCoding { public int Status { get; set; } public ...
- K皇后问题递归解法
#include<iostream> #include<cmath> #include<ctime> using namespace std; bool che ...