题目

给定矩阵A, B和模数p,求最小的正整数x满足 A^x = B(mod p).

分析

与整数的离散对数类似,只不过普通乘法换乘了矩阵乘法。

由于矩阵的求逆麻烦,使用 $A^{km-t} = B(mod \ p)$ 形式的BSGS。

然后就是判断矩阵是否相等,

一种方法是对矩阵进行Hash,

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

#include<bits/stdc++.h>
using namespace std; typedef long long ll;
typedef unsigned long long ull;
const ull base1 = , base2 = ; struct matrix
{
int r, c;
int mat[][];
ull h1, h2;
matrix(){
memset(mat, , sizeof(mat));
h1 = h2 = ; //记得初始化
} void Hash()
{
for(int i = ;i < r;i++)
for(int j = ;j < c;j++)
h1 = h1 * base1 + mat[i][j], h2 = h2 * base2 + mat[i][j];
}
};
int n, p;
matrix A, B; matrix mul(matrix A, matrix B) //矩阵相乘
{
matrix ret;
ret.r = A.r; ret.c = B.c;
for(int i = ;i < A.r;i++)
for(int k = ;k < A.c;k++)
for(int j = ;j < B.c;j++)
{
ret.mat[i][j] = (ret.mat[i][j] + A.mat[i][k] * B.mat[k][j]) % p;
}
return ret;
} matrix mpow(matrix A, int n)
{
matrix ret;
ret.r = A.r; ret.c = A.c;
for(int i = ;i < ret.r;i++) ret.mat[i][i] = ;
while(n)
{
if(n & ) ret = mul(ret, A);
A = mul(A, A);
n >>= ;
}
return ret;
} map<pair<ull, ull>, int>mp;
int BSGS(matrix A, matrix B, int p)
{
int m=sqrt(p)+;mp.clear();
matrix res= B;
for(int i = ;i < m;i++)
{
res.Hash();
mp[make_pair(res.h1, res.h2)] = i;
res = mul(A, res);
}
matrix mi = mpow(A, m);
matrix tmp = mi;
for(int i = ;i <= m+;i++)
{
tmp.Hash();
pair<ull, ull> pa = make_pair(tmp.h1, tmp.h2);
if(mp.count(pa)) return i*m - mp[pa];
tmp = mul(tmp, mi);
}
} void debug_print(matrix a)
{
for(int i = ;i < a.r;i++)
{
for(int j = ;j < a.c;j++){
printf("%d ", a.mat[i][j]);
}
printf("\n");
}
} int main()
{
//srand(NULL);
scanf("%d%d", &n, &p);
A.r = A.c = n;
for(int i = ;i < n;i++)
for(int j = ;j < n;j++){
int tmp;
scanf("%d", &tmp);
A.mat[i][j] = tmp;
}
B.r = B.c = n;
for(int i = ;i < n;i++)
for(int j = ;j < n;j++){
int tmp;
scanf("%d", &tmp);
B.mat[i][j] = tmp;
} ///debug_print(A);
//debug_print(B);
//debug_print(R); printf("%d\n", BSGS(A, B, p));
}

另一种方法是随机产生一个n*1的矩阵f,若A*f=B*f我们则认为这两个矩阵是相等的。为了让直接map矩阵,还要写比较函数(奇怪的是,答案还受比较函数的影响)。

注意矩阵的左乘和右乘。

#include<bits/stdc++.h>
using namespace std; typedef long long ll;
struct matrix
{
int r, c;
int mat[][];
matrix(){
memset(mat, , sizeof(mat));
} bool operator < (const matrix &w) const //???为什么会影响结果呢
{
for (int i=;i< r;i++)
if (mat[i][]<w.mat[i][]) return ;
else if (mat[i][]>w.mat[i][]) return ;
return ;
}
};
int n, p;
matrix A, B, R; //R是随机矩阵 matrix mul(matrix A, matrix B) //矩阵相乘
{
matrix ret;
ret.r = A.r; ret.c = B.c;
for(int i = ;i < A.r;i++)
for(int k = ;k < A.c;k++)
for(int j = ;j < B.c;j++)
{
ret.mat[i][j] = (ret.mat[i][j] + A.mat[i][k] * B.mat[k][j]) % p;
}
return ret;
} matrix mpow(matrix A, int n)
{
matrix ret;
ret.r = A.r; ret.c = A.c;
for(int i = ;i < ret.r;i++) ret.mat[i][i] = ;
while(n)
{
if(n & ) ret = mul(ret, A);
A = mul(A, A);
n >>= ;
}
return ret;
} map<matrix, int>mp;
int BSGS(matrix A, matrix B, matrix R, int p)
{
int m=sqrt(p)+;mp.clear();
matrix res=mul(B, R);
for(int i = ;i < m;i++)
{
mp[res] = i;
res = mul(A, res);
}
matrix mi = mpow(A, m);
matrix tmp = mi;
for(int i = ;i <= m+;i++)
{
matrix t = mul(tmp, R);
if(mp.count(t)) return i*m - mp[t];
tmp = mul(tmp, mi);
}
} void debug_print(matrix a)
{
for(int i = ;i < a.r;i++)
{
for(int j = ;j < a.c;j++){
printf("%d ", a.mat[i][j]);
}
printf("\n");
}
} int main()
{
//srand(NULL);
scanf("%d%d", &n, &p);
A.r = A.c = n;
for(int i = ;i < n;i++)
for(int j = ;j < n;j++){
int tmp;
scanf("%d", &tmp);
A.mat[i][j] = tmp;
}
B.r = B.c = n;
for(int i = ;i < n;i++)
for(int j = ;j < n;j++){
int tmp;
scanf("%d", &tmp);
B.mat[i][j] = tmp;
} R.r = n, R.c = ;
for(int i = ;i < n;i++) R.mat[i][] = rand()%(p-) + p; ///debug_print(A);
//debug_print(B);
//debug_print(R); printf("%d\n", BSGS(A, B, R, p));
}

参考链接:

1. SFN1036 zoj 4128:Matrix BSGS+矩阵乘法

2. GXZlegend【bzoj4128】Matrix 矩阵乘法+Hash+BSGS

bzoj 4128: Matrix ——BSGS&&矩阵快速幂&&哈希的更多相关文章

  1. HDU4887_Endless Punishment_BSGS+矩阵快速幂+哈希表

    2014多校第一题,当时几百个人交没人过,我也暴力交了几发,果然不行. 比完了去学习了BSGS才懂! 题目:http://acm.hdu.edu.cn/showproblem.php?pid=4887 ...

  2. hdu4965 Fast Matrix Calculation 矩阵快速幂

    One day, Alice and Bob felt bored again, Bob knows Alice is a girl who loves math and is just learni ...

  3. BZOJ 2510: 弱题( 矩阵快速幂 )

    每进行一次, 编号为x的数对x, 和(x+1)%N都有贡献 用矩阵快速幂, O(N3logK). 注意到是循环矩阵, 可以把矩阵乘法的复杂度降到O(N2). 所以总复杂度就是O(N2logK) --- ...

  4. BZOJ 1297: [SCOI2009]迷路 [矩阵快速幂]

    Description windy在有向图中迷路了. 该有向图有 N 个节点,windy从节点 0 出发,他必须恰好在 T 时刻到达节点 N-1. 现在给出该有向图,你能告诉windy总共有多少种不同 ...

  5. ACM学习历程——HDU5015 233 Matrix(矩阵快速幂)(2014陕西网赛)

    Description In our daily life we often use 233 to express our feelings. Actually, we may say 2333, 2 ...

  6. HDU 4965 Fast Matrix Calculation 矩阵快速幂

    题意: 给出一个\(n \times k\)的矩阵\(A\)和一个\(k \times n\)的矩阵\(B\),其中\(4 \leq N \leq 1000, \, 2 \leq K \leq 6\) ...

  7. BZOJ 2553 AC自动机+矩阵快速幂 (神题)

    思路: 我们先对所有读进来的T建一个AC自动机 因为走到一个禁忌串就需要回到根 所以呢 搞出来所有的结束点 或一下 fail指针指向的那个点 然后我们就想转移 a[i][j]表示从i节点转移到j节点的 ...

  8. BZOJ 4128 Matrix ——BSGS

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

  9. BZOJ 4128 Matrix BSGS+矩阵求逆

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

随机推荐

  1. LeetCode 23. 合并K个排序链表(Merge Two Sorted Lists)

    23. 合并K个排序链表 23. Merge k Sorted Lists 题目描述 合并 k 个排序链表,返回合并后的排序链表.请分析和描述算法的复杂度. LeetCode23. Merge k S ...

  2. [转帖]SpringBoot集成redisson分布式锁

    SpringBoot集成redisson分布式锁 https://www.cnblogs.com/yangzhilong/p/7605807.html 前几天同事刚让增加上这一块东西. 百度查一下 啥 ...

  3. linux svn开机自动启动服务

    SVN设置开机自动启动 usr/lib/systemd/system/添加svn.service文件 home/sdbdatasvn/svnrepos(换成绝对路径) 如果出现权限问题,请chmod  ...

  4. java笔记——java加载与执行

    java的加载与执行过程: 编译阶段: 首先,我们先创建一个java源文件xxx.java 2. 经过javac.exe编译(如果源文件没有语法错误),生成一个或多个.class文件,注意的是此时的字 ...

  5. PAT(B) 1060 爱丁顿数(Java:21分)

    题目链接:1060 爱丁顿数 (25 point(s)) 题目描述 英国天文学家爱丁顿很喜欢骑车.据说他为了炫耀自己的骑车功力,还定义了一个"爱丁顿数" E ,即满足有 E 天骑车 ...

  6. (二)Django自定义标签

    1.创建自定义标签 在项目的APP中新建一个Python Package-->blog_tags.py 代码: from django import template from ..models ...

  7. VS使用日常

    一.快捷键 1.Ctrl R+E    选中变量快捷自动生成属性

  8. C# HtmlAgilityPack爬取静态页面

    最近对爬虫很感兴趣,稍微研究了一下,利用HtmlAgilityPack制作了一个十分简单的爬虫,这个简易爬虫只能获取静态页面的Html HtmlAgilityPack简介 HtmlAgilityPac ...

  9. Window 使用Nginx 部署 Vue 并把nginx设为windows服务开机自动启动

    1.编译打包Vue项目 在终端输入 npm run build 进行打包编译.等待... 打包完成生成dist文件夹,这就是打包完成的文件. 我们先放着,进行下一步. 2下载Nginx 下载地址: h ...

  10. .net core使用ocelot---第五篇 服务质量

    简介 .net core使用ocelot---第一篇 简单使用  .net core使用ocelot---第二篇 身份验证使用 .net core使用ocelot---第三篇 日志记录  .net c ...