POJ 3070 Fibonacci(快速幂矩阵)

题目链接

不是很了解,线代的行列式和矩阵乘法,忘的差不多了。。。

这个矩阵的n-1次方的左上角那个数就是菲薄那切数列的第n项。快速幂矩阵,和快速幂模差不多,把数相乘换成矩阵相乘了。

渣代码请无视,改天整理一个模版版本。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 using namespace std;
 6 #define MOD 10000
 7 #define LL __int64
 8 int mat[3][3],p[3][3];
 9 void mulp()
10 {
11     int i,j,k;
12     int temp[3][3];
13     memset(temp,0,sizeof(temp));
14     for(i =  1;i <= 2;i ++)
15     {
16         for(j = 1;j <= 2;j ++)
17         {
18             for(k = 1;k <= 2;k ++)
19             {
20                 temp[i][j] += (mat[i][k]*p[k][j])%MOD;
21             }
22         }
23     }
24     for(i = 1;i <= 2;i ++)
25     {
26         for(j = 1;j <= 2;j ++)
27         mat[i][j] = temp[i][j]%MOD;
28     }
29 }
30 void mulm()
31 {
32     int i,j,k;
33     int temp[3][3];
34     memset(temp,0,sizeof(temp));
35     for(i =  1;i <= 2;i ++)
36     {
37         for(j = 1;j <= 2;j ++)
38         {
39             for(k = 1;k <= 2;k ++)
40             {
41                 temp[i][j] += (p[i][k]*p[k][j])%MOD;
42             }
43         }
44     }
45     for(i = 1;i <= 2;i ++)
46     {
47         for(j = 1;j <= 2;j ++)
48         p[i][j] = temp[i][j]%MOD;
49     }
50 }
51 void qmod(LL n)
52 {
53     while(n)
54     {
55         if(n&1)
56         mulp();
57         mulm();
58         n >>= 1;
59     }
60 }
61 int main()
62 {
63     LL n;
64     while(scanf("%I64d",&n)!=EOF)
65     {
66         if(n < 0)
67         break;
68         p[1][1] = p[1][2] = p[2][1] = 1;
69         p[2][2] = 0;
70         mat[1][1] = mat[2][2] = 1;
71         mat[1][2] = mat[2][1] = 0;
72         if(n == 0)
73         {
74             printf("0\n");
75             continue;
76         }
77         qmod(n-1);
78         printf("%d\n",mat[1][1]%MOD);
79     }
80     return 0;
81 }

 

posted @ 2012-09-19 20:20  Naix_x  阅读(231)  评论(0编辑  收藏  举报