题意:链接

方法: 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. 习题:Dual Matrices(思路题/分治)

    tyvj1764 描述一个N行M列的二维矩阵,矩阵的每个位置上是一个绝对值不超过1000的整数.你需要找到两个不相交的A*B的矩形,使得这两个矩形包含的元素之和尽量大.注:A*B的矩形指连续的A行.B ...

  2. 物理课(physics)

    物理课(physics) 题目描述 wzy正在上物理课!他发现了一个完全不会的题目:caoxia在一个奇妙的星球上(重力加速度为gg)踢了一只猫,猫飞起的路线与地面夹角为θθ (角度制),初速度为vv ...

  3. shell 条件表达式

    1.条件测试的常用语法如下 1.test 测试表达式 2.[ 测试表达式 ] #两边需要有空格 3.[[ 测试表达式 ]] 4.(( 测试表达式 )) 说明: 第一种和第二种是等价的,第三种是扩展的t ...

  4. java课后作业-5

    作业一:请写一个类,在任何时候都可以向它查询“你已经创建了多少个对象?“ 程序源代码; public class Lei { /** * @param args */ public static vo ...

  5. ofbiz16 idea 启动

    1.下载gradle并安装到本地 2.idea引入gradle 3.gradle右键选择refresh,项目会重新编译并加载gradle的task 4.可以再编译一下 5.没问题的话打开,jar ap ...

  6. Linq To Entity学习实践

    public class CustomDataContext<TEntity> : System.Data.Linq.DataContext where TEntity : class,n ...

  7. Java中的IO基本用法

    先贴一下我在作业中用到的三种文件输入辅助类.三种文件输出辅助类 public class BuffIn implements InHelp{ private BufferedReader buffer ...

  8. 自定义及发布一个webservice服务

    自定义及发布一个webservice服务    - 声明 某个业务服务为webservice服务       通过@webservice 注解来声明    - 发布webservice服务       ...

  9. Mac air苹果笔记本安装Win10双系统教程(绝对能成功,超详细!)[转]

    转自:http://www.xitonghe.com/jiaocheng/anzhuang-4676.html 在MAc苹果电脑,Mac air上安装Windows7相信大家都已经会了吧,好吧Win7 ...

  10. Lotus Notes Error: your mail file cannot be located. use file location manage location to ensure that your mail file is specified correctly

    在notes客户端中,当我们切换到另一个ID的时候,通过程序发送邮件,会报错: