• BZOJ4128 Matrix


    题目描述:

    给定矩阵A,B和模数p,求最小的x满足 A ^ x  =  B ( mod p)。(p是质数)

    题解:

    同样是BSGS,只是这道题放在了矩阵上。

    其实并不需要矩阵求逆,将BSGS原理中的i * m + j 改为 i * m - j即可。

    代码:

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define ll long long
    int n,p;
    struct matrix
    {
        int s[80][80];
        void read()
        {
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    scanf("%d",&s[i][j]);
        }
        void init()
        {
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    s[i][j]=(i==j);
        }
        int hs()
        {
            int ret = 0;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=n;j++)
                    ret+=s[i][j]*(i+j)%p;
                ret%=p;
            }
            return ret;
        }
    }A,B,M[250];
    matrix operator * (matrix &a,matrix &b)
    {
        matrix ret;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            {
                ret.s[i][j]=0;
                for(int k=1;k<=n;k++)
                    ret.s[i][j]=(ret.s[i][j]+a.s[i][k]*b.s[k][j]%p)%p;
            }
        return ret;
    }
    bool operator == (matrix &a,matrix &b)
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(a.s[i][j]!=b.s[i][j])
                    return 0;
        return 1;
    }
    int hed[20050],cnt;
    struct EG
    {
        int to,nxt;
    }e[250];
    void ae(int f,int t)
    {
        e[++cnt].to = t;
        e[cnt].nxt = hed[f];
        hed[f] = cnt;
    }
    int find(matrix &a)
    {
        int now = a.hs();
        for(int j=hed[now];j;j=e[j].nxt)
            if(M[e[j].to]==a)
                return e[j].to;
        return -1;
    }
    void BSGS()
    {
        M[0]=B;
        ae(M[0].hs(),0);
        int m = (int)sqrt(p);
        matrix MM;
        MM.init();
        for(int i=1;i<=m;i++)
        {
            M[i]=A*M[i-1];
            MM=MM*A;
            if(find(M[i])==-1)
            {
                int now = M[i].hs();
                ae(now,i);
            }
        }
        matrix u;
        u.init();
        for(int i=1;i<=m+2;i++)
        {
            u=u*MM;
            int ans = find(u);
            if(ans!=-1)
            {
                ans=m*i-ans;
                printf("%d
    ",ans);
                break;
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&p);
        A.read();
        B.read();
        BSGS();
        return 0;
    }
  • 相关阅读:
    1030 完美数列 (25 分)
    1029 旧键盘 (20 分)
    数据库命令失败原因汇总
    代码有中文括号,导致错误
    win10笔记本触控板使用指南
    (已解决)vsC#控制台应用添加System.Windows.Forms引用失败(精通C#)
    ildasm中Ctrl+M闪退的问题(已解决, 精通C# 15.1)
    C#控制台应用(.NET Core)添加System.Windows.Forms失败(已解决)
    知识点_指针_增加对指针的理解
    自己写出的Bug_应是%f却写成%d
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10046239.html
Copyright © 2020-2023  润新知