4128: Matrix
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 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
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没啥区别
推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[N][N];
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
*/