BZOJ4128: Matrix 矩阵BSGS
A^x=B(mod C)
令x=im-j
A^(im)=BA^j(mod C)
这就不用求逆元了
#include<bits/stdc++.h> #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<set> #include<map> #include<vector> #include<iomanip> using namespace std; #define ll long long #define ull unsigned long long #define pb push_back #define FOR(a) for(int i=1;i<=a;i++) const int inf=0x3f3f3f3f; const ll Linf=9e18; const int maxn=1e6+7; const ll mod=1e9+7; const double eps=1e-6; #define base 231 ll n,p; struct MATRIX{ ll x[80][80]; void init(){memset(x,0,sizeof x);} MATRIX operator * (MATRIX a){ MATRIX ret; ret.init(); FOR(n)for(int j=1;j<=n;j++){ for(int k=1;k<=n;k++)ret.x[i][j]=ret.x[i][j]+x[i][k]*a.x[k][j]; ret.x[i][j]%=p; } return ret; } ll Hash(){ ll ret=0; FOR(n)for(int j=1;j<=n;j++){ ret=(ret*base+x[i][j])%mod; } return ret; } void read(){ FOR(n)for(int j=1;j<=n;j++) scanf("%lld",&x[i][j]),x[i][j]%=p; } void build(){ init();FOR(n)x[i][i]=1; } }A,B,E; map<ll,ll>mp; void BSGS(){ mp.clear(); ll m=ceil(sqrt(p)); MATRIX ans; for(int i=0;i<=m;i++){ if(i==0){ans=B;mp[ans.Hash()]=i;continue;} ans=ans*A; mp[ans.Hash()]=i; } MATRIX tmp=E; FOR(m)tmp=tmp*A; //A^(im)=BA^j(mod C) ans=E; FOR(m){ ans=ans*tmp; if(mp[ans.Hash()]){ ll ret=i*m-mp[ans.Hash()]; printf("%lld\n",(ret%p+p)%p); return; } } } int main(){ scanf("%lld%lld",&n,&p); A.read();B.read();E.build(); BSGS(); }