题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1757

矩阵相乘,需要构造一个10*10的矩阵。

因为要把(f0 f1 f2...f8 f9) 乘以一个矩阵之后变成(f1 f2 f3 ... f8 f9 f10)

并且f10=a0*f9 + a1*f8 + a2*f7 + ... + a8*f1 + a9*f0 ;

所以构造这样的一个矩阵:

/*                                                       0 0 0 0 0 0 0 0 0 a9
                                                          1 0 0 0 0 0 0 0 0 a8
                                                          0 1 0 0 0 0 0 0 0 a7
                                                          0 0 1 0 0 0 0 0 0 a6
(f0 f1 f2 f3 f4 f5 f6 f7 f8 f9)        *         0 0 0 1 0 0 0 0 0 a5
                                                          0 0 0 0 1 0 0 0 0 a4
                                                          0 0 0 0 0 1 0 0 0 a3
                                                          0 0 0 0 0 0 1 0 0 a2
                                                          0 0 0 0 0 0 0 1 0 a1
                                                          0 0 0 0 0 0 0 0 1 a0

要构造一个后面的10*10的矩阵,记为init,那最后的结果就是 (f0 f1 f2...f8 f9) * init^(k-9) ,得到一个1*10的矩阵, 第一行的最后一个数就是所求 */

View Code
 1 # include<stdio.h>
 2 # include<string.h>
 3 # include<stdlib.h>
 4 int M;
 5 struct matrix{
 6     int A[10][10];
 7 };
 8 matrix power(matrix ans1,matrix ans2)//矩阵相乘
 9 {
10     int i,j,k;
11     matrix ans;
12     for(i=0;i<=9;i++)
13         for(j=0;j<=9;j++)
14         {
15             ans.A[i][j]=0;
16             for(k=0;k<=9;k++)
17             {
18                 ans.A[i][j]+=ans1.A[i][k]*ans2.A[k][j];
19                 ans.A[i][j]%=M;
20             }
21         }
22         return ans;
23 }
24 matrix mod(matrix init,int k)//矩阵快速幂init^k
25 {
26     matrix ans;
27     int i,j;
28     for(i=0;i<=9;i++)
29         for(j=0;j<=9;j++)
30         {
31             if(i==j) ans.A[i][j]=1;
32             else ans.A[i][j]=0;
33         }
34         while(k)
35         {
36             if(k%2) ans=power(ans,init);
37             init=power(init,init);
38             k/=2;
39         }
40         return ans;
41 }
42 int main()
43 {
44     int i,j,k,num,a[10],f[10];
45     matrix init,ans;
46     while(scanf("%d%d",&k,&M)!=EOF)
47     {
48         for(i=0;i<=9;i++)
49             scanf("%d",&a[i]);
50         if(k<=9) {printf("%d\n",k%M);continue;}
51         for(i=0;i<=9;i++)
52             f[i]=i;
53         for(j=0;j<=8;j++)
54             for(i=0;i<=9;i++)
55             {
56                 if(i==j+1) init.A[i][j]=1;
57                 else init.A[i][j]=0;
58             }
59             for(i=0;i<=9;i++)
60                 init.A[i][9]=a[9-i];
61             k=k-9;
62             ans=mod(init,k);
63             num=0;
64             for(i=0;i<=9;i++)
65             {
66                 num+=f[i]*ans.A[i][9];
67                 num%=M;
68             }
69             printf("%d\n",num);
70     }
71     return 0;
72 }
73 /*                                                        0 0 0 0 0 0 0 0 0 a9
74                                                           1 0 0 0 0 0 0 0 0 a8
75                                                           0 1 0 0 0 0 0 0 0 a7
76                                                           0 0 1 0 0 0 0 0 0 a6
77          (f0 f1 f2 f3 f4 f5 f6 f7 f8 f9)         *        0 0 0 1 0 0 0 0 0 a5
78                                                           0 0 0 0 1 0 0 0 0 a4
79                                                           0 0 0 0 0 1 0 0 0 a3
80                                                           0 0 0 0 0 0 1 0 0 a2
81                                                           0 0 0 0 0 0 0 1 0 a1
82                                                           0 0 0 0 0 0 0 0 1 a0
83 
84 要构造一个后面的10*10的矩阵,记为init,那最后的结果就是(f0 f1 f2...f8 f9) * init^(k-9) */

 

posted on 2012-05-09 12:01  奋斗青春  阅读(731)  评论(0编辑  收藏  举报