【BZOJ4128】Matrix,拔山盖世的矩阵乘法+随机化
2016-02-16 16:25
375 查看
写在前面:自这篇blog起,凡是各OJ上的题目就不放题目描述什么的了,直接给链接
传送门
思路:BSGS,由单个数字推广到矩阵
枚举j,接下来有两种方法,一个是存哈希表,但蒟蒻觉得太麻烦,所以就学习了一下随机化,随便搞一个n×1的矩阵C,在等式两边同乘,变成(A^m)^i×C=B×A^j×C(注意顺序!不满足交换律!),然后枚举i,和得到的所有结果比较,碰到就可以输出了
主过程时间复杂度:存结果时O(2*n^2*√p)判断时O(√p*(n^2+√p*n)),好像是这个吧
能让n^3变成n^2,原本跑1.5s的程序就可以优化到0.6s左右了==,而且比hash快一些
代码:
传送门
思路:BSGS,由单个数字推广到矩阵
枚举j,接下来有两种方法,一个是存哈希表,但蒟蒻觉得太麻烦,所以就学习了一下随机化,随便搞一个n×1的矩阵C,在等式两边同乘,变成(A^m)^i×C=B×A^j×C(注意顺序!不满足交换律!),然后枚举i,和得到的所有结果比较,碰到就可以输出了
主过程时间复杂度:存结果时O(2*n^2*√p)判断时O(√p*(n^2+√p*n)),好像是这个吧
能让n^3变成n^2,原本跑1.5s的程序就可以优化到0.6s左右了==,而且比hash快一些
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<map> using namespace std; int n,p,m; struct matrix { int map[72][72]; }a,b,c,hash[145]; inline matrix mul(matrix a,matrix b)//快速幂时的乘法 { matrix c; memset(c.map,0,sizeof(c.map)); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) for (int k=1;k<=n;k++) c.map[i][j]=(c.map[i][j]+a.map[i][k]*b.map[k][j]%p)%p; return c; } matrix cheng(matrix a,matrix b)//随机化后用的乘法 { matrix c; memset(c.map,0,sizeof(c.map)); for (int j=1;j<=n;j++) for (int k=1;k<=n;k++) c.map[j][1]=(c.map[j][1]+a.map[j][k]*b.map[k][1]%p)%p; return c; } inline matrix qr(matrix x,int y)//矩阵快速幂 { matrix z=x; y--; while (y) { if (y&1) z=mul(z,x); x=mul(x,x); y>>=1; } return z; } inline bool pd(matrix x,matrix y) { for (int i=1;i<=n;i++) if (x.map[i][1]!=y.map[i][1]) return 0; return 1; } main() { scanf("%d%d",&n,&p); m=sqrt(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]); for (int i=1;i<=n;i++) c.map[i][1]=i%p; for (int i=0;i<=m;i++) { hash[i]=cheng(b,c); c=cheng(a,c); } a=qr(a,m); for (int i=1;i<=n;i++) c.map[i][1]=i%p; for (int i=1;i<=m;i++) { c=cheng(a,c); for (int j=0;j<=m;j++) if (pd(hash[j],c)){printf("%d",i*m-j);return 0;} } }
相关文章推荐
- radasm相关问题
- LeetCode Missing Number(一次通过)
- tomcat参数配置
- Linux分区
- Nginx源码分析 - 基础数据结构篇 - hash表结构 ngx_hash.c
- JavaScript高级程序设计学习笔记 01
- 一些有用网站
- jquery.layout框架分割线
- webbench压力测试工具
- Struts2基本原理
- linux 配置开机自启动
- poj 2524 Ubiquitous Religions
- WEB压测工具siege用法
- ansible-playbook 安装配置zabbix iptables selinux ntp alipay源
- eclipse 中 *.properties 中 unicode 显示 中文(国际化),需要安装Properties Editor
- ios开发中的C语言学习—— 结构体简介
- git 状态管理
- linux服务器加https
- HTTP协议
- HDU 2955 Robberies 【01背包】