题目描述

给定矩阵A,B和模数p,求最小的x满足

A^x = B (mod p)

输入

第一行两个整数n和p,表示矩阵的阶和模数,接下来一个n * n的矩阵A.接下来一个n * n的矩阵B

输出

输出一个正整数,表示最小的可能的x,数据保证在p内有解

样例输入

2 7
1 1
1 0
5 3
3 2

样例输出

4


题解

矩阵乘法+Hash+BSGS

看到题目很容易想到BSGS算法,但要求逆元,而矩阵的逆不是很好求出,怎么办?

事实上,BSGS有两种形式:$a^{km+t}\equiv(mod\ p)$和$a^{km-t}\equiv b(mod\ p)$

第一种形式是经典的BSGS,并可以应用到EXBSGS中,而第二种形式的优点在于不需要求逆元,放到此题中就是不需要求矩阵的逆。

按照BSGS的思路,原题可化为$A^{km}\equiv B*A^t(mod\ p)$

于是我们便可以把$B*A^t(mod\ p)$存到map中,然后枚举k的取值来查询。

如何快速查询?就需要使用Hash。

这里为了防止两个不同矩阵的Hash值冲突,使用了两个底数进行Hash。

然后就可以愉快的套BSGS的板子了~

#include <cstdio>
#include <cmath>
#include <cstring>
#include <map>
#include <utility>
#define N 75
using namespace std;
typedef unsigned long long ull;
const ull base1 = 100003 , base2 = 1000003;
int n , p;
struct data
{
ull v[N][N] , val1 , val2;
data(int x)
{
int i;
memset(v , 0 , sizeof(v)) , val1 = val2 = 0;
for(i = 1 ; i <= n ; i ++ ) v[i][i] = x;
}
data operator*(const data a)const
{
int i , j , k;
data ans(0);
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= n ; j ++ )
for(k = 1 ; k <= n ; k ++ )
ans.v[i][j] = (ans.v[i][j] + v[i][k] * a.v[k][j]) % p;
return ans;
}
void hash()
{
int i , j;
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= n ; j ++ )
val1 = val1 * base1 + v[i][j] , val2 = val2 * base2 + v[i][j];
}
};
map<pair<ull , ull> , int> f;
map<pair<ull , ull> , int>::iterator it;
int main()
{
int i , j , k , m;
scanf("%d%d" , &n , &p) , m = (int)ceil(sqrt(p));
data A(0) , B(0) , C(1) , D(1);
for(i = 1 ; i <= n ; i ++ ) for(j = 1 ; j <= n ; j ++ ) scanf("%llu" , &A.v[i][j]);
for(i = 1 ; i <= n ; i ++ ) for(j = 1 ; j <= n ; j ++ ) scanf("%llu" , &B.v[i][j]);
for(i = 1 ; i <= m ; i ++ ) B = B * A , B.hash() , f[make_pair(B.val1 , B.val2)] = i;
for(i = 1 ; i <= m ; i ++ ) C = C * A;
for(i = 1 ; i <= m ; i ++ )
{
D = D * C , D.hash() , it = f.find(make_pair(D.val1 , D.val2));
if(it != f.end())
{
printf("%d\n" , i * m - it->second);
return 0;
}
}
return 0;
}

最新文章

  1. 在IIS下部署Thinkphp项目,验证码不能显示的解决办法
  2. VS2013 Community配置OpenCV3.0.0
  3. Jquery自定义扩展方法(二)--HTML日历控件
  4. JMeter设置集合点
  5. 经典DP 二维换一维
  6. 方法javaJVM学习笔记-内存处理
  7. unix network programming(3rd)Vol.1 [第1章]《读书笔记系列》
  8. C# 进销存系统开发框架
  9. Codeforces Round #279 (Div. 2)f
  10. SD卡FAT32获得高速的文件格式(图文介绍)
  11. MVC源码解析 - HttpRuntime解析
  12. 【简单dp】 poj 2346
  13. 使用原生 JavaScript 操作 DOM
  14. Github--账号重新申请与配置
  15. MVC文件夹及文件说明
  16. ASP.NET VS2013 Office 转 PDF
  17. VS2010中NET4项目中使用LOG4NET办法
  18. JavaScript中push ,pop ,concat ,join方法
  19. JavaBean转JSON方式
  20. 关于基线baseline及与inline-block、vertical-aline等属性的关系(完善中.......)

热门文章

  1. 2017.10.1 QBXT 模拟赛
  2. python基础教程总结7——异常
  3. 将Java应用部署到SAP云平台neo环境的两种方式
  4. Unity四元素运用之风向标跟随箭头
  5. [手势识别] CNN + OpenCV 手势识别记录
  6. VA助手添加扩展文件后缀名
  7. PayPal为什么从Java迁移到Node.js 性能提高一倍 文件代码减少44%
  8. 远程连接 mySql数据库
  9. bash编程之case语句,函数
  10. sql where in字符串问题