BZOJ4128: Matrix 矩阵BSGS

来源:互联网 发布:skype for ubuntu 14 编辑:程序博客网 时间:2024/06/05 00:52

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 231ll 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();}