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 }

 

posted @ 2014-08-20 17:27  galaxy77  阅读(210)  评论(0编辑  收藏  举报