[BZOJ4128]Matrix(BSGS+矩乘)

版权声明:转载请注明出处:http://blog.csdn.net/clove_unique https://blog.csdn.net/Clove_unique/article/details/71698783

题目描述

传送门

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

题解

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

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
using namespace std;
#define N 75

struct 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);
}

猜你喜欢

转载自blog.csdn.net/Clove_unique/article/details/71698783