Blocks(POJ 3734 矩阵快速幂)

Blocks

Input

The first line of the input contains an integer T(1≤T≤100), the number of test cases. Each of the next T lines contains an integer N(1≤N≤10^9) indicating the number of blocks.

Output

For each test cases, output the number of ways to paint the blocks in a single line. Since the answer may be quite large, you have to module it by 10007.

Sample Input

2  //T
1  //N
2

Sample Output

2
6
给定n方块染色,颜色有红黄绿蓝,问红绿都是偶数的情况有多少种。先要写出递推公式,见:


最开始的情况是2,2,0,乘以该矩阵,当然直接求n次幂答案也是对的
 1 #include <cstring>
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <map>
 6 using namespace std;
 7 #define MOD 10007
 8 typedef long long LL;
 9 int T,n;
10 struct Matrix
11 {
12     LL mat[3][3];
13 };
14 Matrix mul(Matrix a,Matrix b)
15 {
16     Matrix c;
17     for(int i=0;i<3;i++)
18     {
19         for(int j=0;j<3;j++)
20         {
21             c.mat[i][j]=0;
22             for(int k=0;k<3;k++)
23                 c.mat[i][j]=(c.mat[i][j]+a.mat[i][k]*b.mat[k][j])%MOD;
24         }
25     }
26     return c;
27 }
28 Matrix mod_pow(Matrix x,LL n)
29 {
30     Matrix res;
31     memset(res.mat,0,sizeof(res.mat));
32     for(int i=0;i<3;i++)
33         res.mat[i][i]=1;
34     while(n)
35     {
36         if(n&1)
37             res=mul(res,x);
38         x=mul(x,x);
39         n>>=1;
40     }
41     return res;
42 }
43 int main()
44 {
45     Matrix p;
46     p.mat[0][0]=2,p.mat[0][1]=1,p.mat[0][2]=0;
47     p.mat[1][0]=p.mat[1][1]=p.mat[1][2]=2;
48     p.mat[2][0]=0,p.mat[2][1]=1,p.mat[2][2]=2;
49     cin>>T;
50     while(T--)
51     {
52         cin>>n;
53         Matrix ans=mod_pow(p,n);
54         cout<<ans.mat[0][0]<<endl;
55     }
56 }

 

posted @ 2016-05-05 17:03  御心飞行  阅读(199)  评论(0编辑  收藏  举报