您的位置:首页 > 其它

BZOJ 4128: Matrix BSGS 矩阵乘法

2017-11-23 16:28 288 查看

4128: Matrix

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 660  Solved: 363

[Submit][Status][Discuss]

Description

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

A^x = B (mod p)


Input

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

Output

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

Sample Input

2 7

1 1

1 0

5 3

3 2

Sample Output

4

HINT

对于100%的数据,n <= 70,p <=19997,p为质数,0<= A_{ij},B_{ij}< p
保证A有逆

除了数变成矩阵

和普通的BSGS没啥区别

BSGS传送门

推map的时候脑瘫 用qpow了。。TLE一发

#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<string>
#include<bitset>
#include<queue>
#include<set>
#include<map>
using namespace std;

typedef long long ll;

inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch<='9'&&ch>='0'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return f*x;
}
void print(int x)
{if(x<0)putchar('-'),x=-x;if(x>=10)print(x/10);putchar(x%10+'0');}

const int N=75;

int n,mod;

struct matrix
{
int m

;

matrix(){memset(m,0,sizeof(m));}

friend matrix operator *(const matrix &x,const matrix &y)
{
matrix res;
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
for(int k=1;k<=n;++k)
(res.m[i][j]+=x.m[i][k]*y.m[k][j])%=mod;
return res;
}

friend matrix qpow(matrix x,int y)
{
matrix res=x;
y--;
while(y)
{
if(y&1)res=res*x;
x=x*x;
y>>=1;
}
return res;
}

friend bool operator <(const matrix &x,const matrix &y)
{
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
if(x.m[i][j]<y.m[i][j])
return 1;
else if(x.m[i][j]>y.m[i][j])
return 0;
return 0;
}

}a,b;

map<matrix,int>mp;

int BSGS()
{
int m=ceil(sqrt(mod));
matrix tmp=a;
mp[a]=1;
for(int i=2;i<=m;++i)
tmp=tmp*a,
mp[b*tmp]=i;
matrix ine;
for(int i=1;i<=n;++i)
ine.m[i][i]=1;
for(int i=1;i<=m;++i)
{
ine=ine*tmp;
if(mp[ine])
{
return (i*m-mp[ine]+mod)%mod;
}
}
}

int main()
{
n=read();mod=read();
register int i,j;
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
a.m[i][j]=read();
for(i=1;i<=n;++i)
for(j=1;j<=n;++j)
b.m[i][j]=read();
cout<<BSGS()<<endl;
return 0;
}
/*
2 7
1 1
1 0
5 3
3 2

4
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: