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("\n");
50     }
51     printf("fin\n");
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\n",ans);
81     return 0;
82 }

 

posted @ 2017-03-16 23:22  SilverNebula  阅读(192)  评论(0编辑  收藏  举报
AmazingCounters.com