题意:链接

方法: 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. algorithm 头文件

    非修改性序列操作(12个) 循环 对序列中的每个元素执行某操作 for_each() 查找 在序列中找出某个值的第一次出现的位置 find() 在序列中找出符合某谓词的第一个元素 find_if() ...

  2. java 数据库连接 驱动相关参数

    mysql: driverClass=com.mysql.jdbc.Driver connectionURL=jdbc:mysql://localhost:3306/shiro userId=root ...

  3. POJ 2836:Rectangular Covering(状态压缩DP)

    题目大意:在一个平面内有若干个点,要求用一些矩形覆盖它们,一个矩形至少覆盖两个点,可以相互重叠,求矩形最小总面积. 分析: 数据很小,很容易想到状压DP,我们把点是否被覆盖用0,1表示然后放在一起得到 ...

  4. 折线统计(line)

    折线统计(line) 题目描述 二维平面上有n个点(xi, yi),现在这些点中取若干点构成一个集合S,对它们按照x坐标排序,顺次连接,将会构成一些连续上升.下降的折线,设其数量为f(S).如下图中, ...

  5. MacPro 系统空间竟占90G,如何清理--OmniDiskSweeper

    MacPro 经常提示我磁盘空间已满,管理磁盘空间. 然后我就管理了一下,发现系统竟占90个G,有点懵逼.然后网上查了资料,发现这个超级好用的工具OmniDiskSweeper. 打开是这样的! 然后 ...

  6. HDOJ 1085 Holding Bin-Laden Captive!

    Holding Bin-Laden Captive! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Ja ...

  7. POJ1927 Area in Triangle

      Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 1458   Accepted: 759 Description Give ...

  8. Eclipse与MyEclipse修改注释字体颜色

    修改配置路劲 Window--->Preferences--->Java--->Editor--->Syntax Coloring--->Element--->Co ...

  9. 用Razor来生成模板 using razor for template

    原文发布时间为:2011-09-15 -- 来源于本人的百度文章 [由搬家工具导入] http://razorengine.codeplex.com/

  10. 关于platform_device和platform_driver的匹配【转】

    转自:http://blog.csdn.net/dfysy/article/details/5959451 版权声明:本文为博主原创文章,未经博主允许不得转载. 说句老实话,我不太喜欢现在Linux ...