• 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;
    }
  • 相关阅读:
    Leetcode-645 Set Mismatch
    2017百度软研(C++)
    二叉树中任意两个节点的最近公共祖先
    不用加减乘除做加法
    一些leetcode算法题
    Leetcode 98. Validate Binary Search Tree
    C++ 通过ostringstream 实现任意类型转string
    Leetcode 215. Kth Largest Element in an Array
    382. Linked List Random Node
    一些基础函数的实现
  • 原文地址:https://www.cnblogs.com/LiGuanlin1124/p/10046239.html
Copyright © 2020-2023  润新知