题意:链接

方法: 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+矩阵求逆的更多相关文章

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

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

  2. BZOJ 4128 Matrix ——BSGS

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

  3. BZOJ 4128: Matrix

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

  4. BZOJ 4128: Matrix (矩阵BSGS)

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

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

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

  6. 【BZOJ】4128: Matrix

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

  7. bzoj 4128 矩阵求逆

    /************************************************************** Problem: 4128 User: idy002 Language: ...

  8. BZOJ4128: Matrix(BSGS 矩阵乘法)

    Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 813  Solved: 442[Submit][Status][Discuss] Descriptio ...

  9. 【BZOJ4128】Matrix BSGS+hash

    [BZOJ4128]Matrix Description 给定矩阵A,B和模数p,求最小的x满足 A^x = B (mod p) Input 第一行两个整数n和p,表示矩阵的阶和模数,接下来一个n * ...

随机推荐

  1. BZOJ 2190:[SDOI2008]仪仗队(欧拉函数)

    [SDOI2008]仪仗队 Description 作为体育委员,C君负责这次运动会仪仗队的训练.仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视 ...

  2. GDOI2018前夕 错误总结

    算法易错点 $FFT$ 1.注意精度,以及是否取整 2.注意$complex$类不要写错,复数乘法是这样的: complex operator *(const complex &b){retu ...

  3. Maven构建多模块项目

    使用Maven构建多模块项目 转自:http://www.cnblogs.com/xdp-gacl/p/4242221.html 在平时的Javaweb项目 开发中为了便于后期的维护,我们一般会进行分 ...

  4. 江南乐(bzoj 3576)

    Description 小A是一个名副其实的狂热的回合制游戏玩家.在获得了许多回合制游戏的世界级奖项之后,小A有一天突然想起了他小时候在江南玩过的一个回合制游戏.    游戏的规则是这样的,首先给定一 ...

  5. Java语法糖(二)

    语法糖之四:内部类 内部类:顾名思义,在类的内部在定义一个类.内部类仅仅是编译时的概念,编译成字节码后,内部类会生成单独的Class文件. 四种:成员内部类.局部内部类.匿名内部类.静态内部类. 1. ...

  6. Select语句执行顺序《转》

    原文发布时间为:2010-10-12 -- 来源于本人的百度文章 [由搬家工具导入] 目的在于理解如何Select 【搜索所得】: 标准的 SQL 的解析顺序为:(1).FROM 子句, 组装来自不同 ...

  7. Method, apparatus, and system for speculative abort control mechanisms

    An apparatus and method is described herein for providing robust speculative code section abort cont ...

  8. python 锁 多进程

    参考: http://www.cnblogs.com/huxi/archive/2010/06/26/1765808.html http://linhs.blog.51cto.com/370259/1 ...

  9. xammp无法启动apache 由于80端口引起的问题 摘自百度经验

    启动过程提示: 15:33:05 [Apache] Problem detected!15:33:05 [Apache] Port 80 in use by "Unable to open ...

  10. python 编码问题之终极解决

    结合之前遇到的坑以及下面贴的这篇文章, 总结几种python乱码解决方案,如果遇到乱码,不妨尝试一下? 1,必备 #encoding=utf-8 2, python编程环境编码 import sys ...