[BZOJ4128]Matrix(BSGS+矩乘)

来源:互联网 发布:能赚集分宝的软件 编辑:程序博客网 时间:2024/05/16 06:23

题目描述

传送门

题目大意:给出矩阵AB和模数p,求最小的正整数x,满足AxB(modp)

题解

裸的BSGS,直接换成矩阵乘法就好了
注意map里放结构体的话要重载一下<和==

代码

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<map>using namespace std;#define N 75struct data{    int a[N][N];    bool operator == (const data &b) const    {        for (int i=1;i<=70;++i)            for (int j=1;j<=70;++j)                if (a[i][j]!=b.a[i][j]) return 0;        return 1;    }    bool operator < (const data &b) const    {        for (int i=1;i<=70;++i)            for (int j=1;j<=70;++j)            {                if (a[i][j]<b.a[i][j]) return 1;                if (a[i][j]>b.a[i][j]) return 0;            }        return 0;    }}zero,unit,A,B,A_m;int n,ans,m,p;map <data,int> hash;data cheng(data a,data b){    data ans=zero;    for (int k=1;k<=n;++k)        for (int i=1;i<=n;++i)            for (int j=1;j<=n;++j)                ans.a[i][j]=(ans.a[i][j]+a.a[i][k]*b.a[k][j]%p)%p;    return ans;}data fast_pow(data a,int p){    data ans=unit;    for (;p;p>>=1,a=cheng(a,a))        if (p&1)            ans=cheng(ans,a);    return ans;}int main(){    scanf("%d%d",&n,&p);    for (int i=1;i<=n;++i) unit.a[i][i]=1;    for (int i=1;i<=n;++i)        for (int j=1;j<=n;++j)            scanf("%d",&A.a[i][j]);    for (int i=1;i<=n;++i)        for (int j=1;j<=n;++j)            scanf("%d",&B.a[i][j]);    m=ceil(sqrt(p));    A_m=fast_pow(A,m);    data mi=B;    hash[mi]=1;    for (int i=1;i<=m;++i)    {        mi=cheng(mi,A);        hash[mi]=i+1;    }    mi=unit;    for (int i=1;i<=m;++i)    {        mi=cheng(mi,A_m);        if (hash[mi])        {            ans=i*m-hash[mi]+1;            break;        }    }    printf("%d\n",ans);}
0 0