hdu 4965 Fast Matrix Calculation 快速矩阵幂
【题意】一个矩阵N*K的矩阵A,一个K*N的矩阵B,(4 <= N <= 1000,2 <=K <= 6)。先进行矩阵乘法C=A*B,然后进行D=C^(N*N)的幂运算,然后
对D的每个数对6取模,最后求出D的所有位置数字之和。
【解法】 直接按照题目上的做 A*B 形成一个N*N的矩阵C,再用C求其n*n次幂。这样果断超时啊。
看了题解(AB)^n 可以写成 A (BA)^(n-1) B , B*A 形成的矩阵就是K*K的,这里果断省了一大把时间啊,这么简单的变换为毛我们就是没想到泪奔
【注意】平时都是用结构体进行快速幂运算,但是要是结构体里的数组太大了就会ce。这里我只有一部分是用的结构体,后一部分用的数组。
1 #include<iostream> 2 #include<cstdio> 3 #include<map> 4 #include<algorithm> 5 #include<cstring> 6 #define INF 9999999 7 using namespace std; 8 struct node 9 { 10 int mat[7][7]; 11 } no; 12 13 int a[1002][7],b[7][1002],cc[1002][1002],aa[1002][7]; 14 15 16 node mul(node a,node b,int n,int m,int p) 17 { 18 node c; 19 memset(c.mat,0,sizeof(c.mat)); 20 for(int i=0; i<n; i++) 21 for(int j=0; j<m; j++) 22 if(a.mat[i][j]) 23 { 24 for(int k=0; k<p; k++) 25 c.mat[i][k]=(c.mat[i][k]+a.mat[i][j]*b.mat[j][k])%6; 26 } 27 return c; 28 } 29 30 node solve(node a,int num,int n) 31 { 32 node b; 33 memset(b.mat,0,sizeof(b.mat)); 34 for(int i=0; i<n; i++) 35 b.mat[i][i]=1; 36 while(num) 37 { 38 if(num%2) 39 b=mul(b,a,n,n,n); 40 a=mul(a,a,n,n,n); 41 num/=2; 42 } 43 return b; 44 } 45 46 int main() 47 { 48 int n,m; 49 while(~scanf("%d%d",&n,&m)) 50 { 51 if(n==0&&m==0) 52 break; 53 for(int i=0; i<n; i++) 54 for(int j=0; j<m; j++) 55 scanf("%d",&a[i][j]); 56 57 for(int i=0; i<m; i++) 58 for(int j=0; j<n; j++) 59 scanf("%d",&b[i][j]); 60 61 memset(no.mat,0,sizeof(no.mat)); 62 for(int i=0; i<m; i++) 63 for(int j=0; j<n; j++) 64 if(b[i][j]) 65 { 66 for(int k=0; k<m; k++) 67 no.mat[i][k]=(no.mat[i][k]+b[i][j]*a[j][k])%6; 68 } 69 70 no=solve(no,n*n-1,m); 71 72 memset(aa,0,sizeof(aa)); 73 for(int i=0; i<n; i++) 74 for(int j=0; j<m; j++) 75 if(a[i][j]) 76 { 77 for(int k=0; k<m; k++) 78 aa[i][k]=(aa[i][k]+a[i][j]*no.mat[j][k])%6; 79 } 80 81 memset(cc,0,sizeof(cc)); 82 for(int i=0; i<n; i++) 83 for(int j=0; j<m; j++) 84 if(aa[i][j]) 85 { 86 for(int k=0; k<n; k++) 87 cc[i][k]=(cc[i][k]+aa[i][j]*b[j][k])%6; 88 } 89 int ans=0; 90 for(int i=0; i<n; i++) 91 for(int j=0; j<n; j++) 92 ans+=cc[i][j]; 93 printf("%d\n",ans); 94 } 95 return 0; 96 }