• 【题解】【BZOJ】BZOJ4128 Matrix


    BZOJ4128 Matrix

    BZOJ4128 Matrix

    1 题外话

    调了半天竟是因为比较函数打错

    2 sol

    矩阵离散对数

    令(x=Alceil sqrt{p} ceil -B) ,其中(0leqslant A,B leq lceil sqrt{p} ceil)

    则有(a^{Asqrt{p}-B} = b)

    所以(a^{Asqrt{p}}=ba^{B})

    枚举$B$,得到右侧所有取值,存进map里,再枚举(A) ,寻找是否有对应的B

    找到后(x=Alceil sqrt{p} ceil -B)

    时间复杂度(O(sqrt{p}))

    和正常BSGS的推导毫无区别

    3 code

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <map>
    #include <cmath>
    using namespace std;
    
    const int N=80;
    
    inline void read(int &x) {
        x=0;
        int f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9') {
            if (ch=='-') {
                f=-1;
            }
            ch=getchar();
        }
        while(ch>='0'&&ch<='9') {
            x=x*10+ch-'0';
            ch=getchar();
        }
        x*=f;
    }
    
    int n,p;
    
    struct mat {
        int a[N][N];
        mat() {
            memset(a,0,sizeof(a));
        }
        inline void init() {
            for(int i=1;i<=n;i++) {
                a[i][i]=1;
            }
        }
        inline void input() {
            for(int i=1;i<=n;i++) {
                for(int j=1;j<=n;j++) {
                    read(a[i][j]);
                }
            }
        }
        inline void output() {
            for(int i=1;i<=n;i++) {
                for(int j=1;j<=n;j++) {
                    printf("%d ",a[i][j]);
                }
                puts("");
            }
        }
    };
    
    mat I;
    
    mat operator * (const mat &x,const mat &y) {
        mat ans;
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=n;j++) {
                for(int k=1;k<=n;k++) {
                    ans.a[i][j]+=x.a[i][k]*y.a[k][j];
                    ans.a[i][j]%=p;
                }
            }
        }
        return ans;
    }
    
    bool operator == (const mat &x,const mat &y) {
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=n;j++) {
                if (x.a[i][j]!=y.a[i][j]) {
                    return 0;
                }
            }
        }
        return 1;
    }
    
    bool operator < (const mat &x,const mat &y) {
        for(int i=1;i<=n;i++) {
            for(int j=1;j<=n;j++) {
                if (x.a[i][j]<y.a[i][j]) {
                    return 1;
                }
                if (x.a[i][j]>y.a[i][j]) {
                    return 0;
                }
            }
        }
        return 0;
    }
    
    inline mat mat_pow(mat base,int p) {
        mat ans;
        ans.init();
        while(p) {
            if (p&1) {
                ans=ans*base;
            }
            base=base*base;
            p>>=1;
        }
        return ans;
    }
    
    inline int BSGS(mat a,mat b) {
        if (b==I) {
            return 0;
        }
        map<mat,int> mp;
        int m=ceil(sqrt(p));
        mat ax=b;
        mp[ax]=0;
        for(int i=1;i<=m;i++) {
            ax=ax*a;
            mp[ax]=i;
        }
        mat am=mat_pow(a,m);
        mat aj=am;
        for(int i=1;i<=m;i++) {
            if (mp[aj]) {
                return i*m-mp[aj];
            }
            aj=aj*am;
        }
        return -1;
    }
    
    int main() {
        read(n),read(p);
        I.init();
        mat A,B;
        A.input();
        B.input();
        printf("%d
    ",BSGS(A,B));
        return 0;
    }
    
    

    4 注意

    map要重载小于运算符和等于运算符

    小于的重载最后如果写成return 1就会找不到目标,原因不明

    Author: tt66ea

    Created: 2021-07-16 周五 19:54

    Validate

  • 相关阅读:
    学习python报错处理
    Java命名规则
    python打开文件可以有多种模式
    python中的异常
    python中的构造函数和构造函数和析构函数的作用
    学习网址
    使用Python+selenium过程中所需安装的库和软件
    oracle 、server和my sql 语法区别
    blob(斑点)特征,SimpleBlobDetector(OpenCV案例源码detect_blob.cpp解读)
    查找与绘制轮廓findContours()、drawContours()(OpenCV案例源码contours2.cpp解读)
  • 原文地址:https://www.cnblogs.com/tt66ea-blog/p/15021670.html
Copyright © 2020-2023  润新知