zoukankan      html  css  js  c++  java
  • Bzoj4128 Matrix

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 530  Solved: 279

    Description

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

    Input

    第一行两个整数n和p,表示矩阵的阶和模数,接下来一个n * n的矩阵A.接下来一个n * n的矩阵B

    Output

    输出一个正整数,表示最小的可能的x,数据保证在p内有解

    Sample Input

    2 7
    1 1
    1 0
    5 3
    3 2

    Sample Output

    4

    HINT

    对于100%的数据,n <= 70,p <=19997,p为质数,0<= A_{ij},B_{ij}< p

    保证A有逆

    数学 矩阵乘法 BSGS

    矩阵上的BSGS,除了重载一堆东西简直烦以外,本质上还是一个BSGS。

    好像有特殊的hash技巧可以让判重变得十分简便。

    然而我选择了暴力

     1 /*by SilverN*/
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<cstdio>
     6 #include<cmath>
     7 #include<vector>
     8 #include<map>
     9 using namespace std;
    10 const int mxn=71;
    11 int read(){
    12     int x=0,f=1;char ch=getchar();
    13     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    14     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    15     return x*f;
    16 }
    17 int n,P;
    18 struct Mat{
    19     int a[mxn][mxn];
    20     friend Mat operator * (const Mat &x,const Mat &y){
    21         Mat res;
    22         int i,j,k;
    23         for(i=1;i<=n;i++)
    24             for(j=1;j<=n;j++){
    25                 res.a[i][j]=0;
    26                 for(k=1;k<=n;k++)
    27                     (res.a[i][j]+=x.a[i][k]*y.a[k][j])%=P;
    28             }
    29         return res;
    30     }
    31     friend bool operator < (const Mat &x,const Mat &y){
    32         for(int i=1;i<=n;i++)
    33             for(int j=1;j<=n;j++)
    34                 if(x.a[i][j]^y.a[i][j])
    35                     return (x.a[i][j]<y.a[i][j]);
    36         return false;
    37     }
    38     friend bool operator == (const Mat &x,const Mat &y){
    39         for(int i=1;i<=n;i++)
    40             for(int j=1;j<=n;j++)
    41                 if(x.a[i][j]^y.a[i][j])return 0;
    42         return 1;
    43     }
    44 }a,b,c;
    45 map<Mat,int>mp;
    46 void Debug(Mat x){
    47     for(int i=0;i<=n;i++){
    48         for(int j=0;j<=n;j++)printf("%d ",x.a[i][j]);
    49         printf("
    ");
    50     }
    51     printf("fin
    ");
    52 }
    53 int main(){
    54     int i,j;
    55     n=read();P=read();
    56     for(i=1;i<=n;i++)
    57         for(j=1;j<=n;j++)
    58             a.a[i][j]=read();
    59     for(i=1;i<=n;i++)
    60         for(j=1;j<=n;j++)
    61             b.a[i][j]=read();
    62     c=a;
    63     int m=sqrt(P)+1;
    64     for(i=1;i<=m;i++){
    65         Mat tmp=b*c;
    66         if(!mp.count(tmp)){
    67             mp[tmp]=i;
    68         }
    69         if(i<m)c=c*a;
    70     }
    71     a=c;
    72     int ans=0x3f3f3f3f;
    73     for(i=m;i<=P;i+=m){
    74         if(mp.count(a)){
    75             ans=i-mp[a];
    76             break;
    77         }
    78         a=a*c;
    79     }
    80     printf("%d
    ",ans);
    81     return 0;
    82 }
  • 相关阅读:
    [转载] 关于mkvtoolnix批量处理的
    转载:JMeter压力测试入门教程[图文]
    分享 stormzhang的Andoid学习之路
    Sublime Text 2 插件
    PHP 操作SQLite
    curl 远程下载图片
    centos lamp 配置
    php 例子 如何转换ISO8601为 utc时间
    php 常用 常量集合
    php 文档操作
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6562243.html
Copyright © 2011-2022 走看看