UVA 12470 - Tribonacci(快速幂矩阵)

题目链接

开始居然错以为是Fib,其实是Trib,对矩阵加深了一下认识,F(n) = F(n-1)+F(n-2)+F(n-3) 初始矩阵变为3阶了。幂模依旧很搓,搜很多个版本,基本上都是运算符重载的,还有调用数组名的,当然也有直接运算的,凑合着用吧。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <cstdlib>
 6 using namespace std;
 7 #define MOD 1000000009
 8 #define LL long long
 9 LL p[3][3],mat[3][3];
10 LL qmod(LL n)
11 {
12     int i,j,k;
13     LL c[3][3];
14     while(n)
15     {
16         if(n&1)
17         {
18             memset(c,0,sizeof(c));
19             for(i = 0; i <= 2; i ++)
20                 for(j = 0; j <= 2; j ++)
21                     for(k = 0; k <= 2; k ++)
22                     {
23                         c[i][j] += mat[i][k]*p[k][j];
24                         c[i][j] %= MOD;
25                     }
26             memcpy(mat,c,sizeof(mat));
27         }
28         memset(c,0,sizeof(c));
29         for(i = 0; i <= 2; i ++)
30             for(j = 0; j <= 2; j ++)
31                 for(k = 0; k <= 2; k ++)
32                 {
33                     c[i][j] += p[i][k]*p[k][j];
34                     c[i][j] %= MOD;
35                 }
36         memcpy(p,c,sizeof(p));
37         n >>= 1;
38     }
39     return (2*mat[0][0]+mat[0][1])%MOD;
40 }
41 int main()
42 {
43     int i,j;
44     LL n,ans;
45     while(scanf("%lld",&n)!=EOF)
46     {
47         if(n == 0)
48             break;
49         memset(p,0,sizeof(p));
50         p[0][1] = p[0][2] = p[0][0] = 1;
51         p[1][0] = 1;
52         p[2][1] = 1;
53         for(i = 0; i <= 2; i ++)
54             for(j = 0; j <= 2; j ++)
55                 if(i == j)
56                     mat[i][j] = 1;
57                 else
58                     mat[i][j] = 0;
59         if(n <= 3)
60         {
61             printf("%lld\n",n-1);
62             continue;
63         }
64         printf("%lld\n",qmod(n-3));
65     }
66     return 0;
67 }
posted @ 2012-09-20 14:00  Naix_x  阅读(393)  评论(0编辑  收藏  举报