[POJ3734]Blocks(递推,矩阵快速幂)

题目链接:http://poj.org/problem?id=3734

题意:n个方块4个颜色,现在要求涂色,其中两种颜色的数量是偶数,问多少种情况。

考虑sta(i)为当前i块的时候的合法涂色种类数,则有:EE、OE(EO)、OO三种情况。

EEi = 2 * EE(i-1) + OE(EO)(i-1)

OOi = OE(EO)i + 2 * OO(i-1)

OE(EO)i = 2 * (OO(i-1) + OE(EO)(i-1) + EE(i-1))

抽取出系数,矩阵为

|2 1 0|

|0 1 2|

|2 2 2|

最终合法为EEn,则是第一行第一列。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <iomanip>
 4 #include <cstring>
 5 #include <climits>
 6 #include <complex>
 7 #include <cassert>
 8 #include <cstdio>
 9 #include <bitset>
10 #include <vector>
11 #include <deque>
12 #include <queue>
13 #include <stack>
14 #include <ctime>
15 #include <set>
16 #include <map>
17 #include <cmath>
18 using namespace std;
19 
20 typedef long long LL;
21 
22 const int mod = 10007;
23 const int maxn = 100;
24 typedef struct Matrix {
25     int m[maxn][maxn];
26     int r;
27     int c;
28     Matrix() {
29         r = c = 0;
30         memset(m, 0, sizeof(m));
31     }
32 } Matrix;
33 
34 Matrix mul(Matrix m1, Matrix m2, int mod) {
35     Matrix ans = Matrix();
36     ans.r = m1.r;
37     ans.c = m2.c;
38     for(int i = 1; i <= m1.r; i++) {
39         for(int j = 1; j <= m2.r; j++) {
40             for(int k = 1; k <= m2.c; k++) {
41                 if(m2.m[j][k] == 0) continue;
42                 ans.m[i][k] = ((ans.m[i][k] + m1.m[i][j] * m2.m[j][k] % mod) % mod) % mod;
43             }
44         }
45     }
46     return ans;
47 }
48 
49 Matrix quickmul(Matrix m, int n, int mod) {
50     Matrix ans = Matrix();
51     for(int i = 1; i <= m.r; i++) ans.m[i][i]  = 1;
52     ans.r = m.r;
53     ans.c = m.c;
54     while(n) {
55         if(n & 1) ans = mul(m, ans, mod);
56         m = mul(m, m, mod);
57         n >>= 1;
58     }
59     return ans;
60 }
61 
62 int n;
63 
64 int main() {
65 //    freopen("in", "r", stdin);
66     int T;
67     scanf("%d", &T);
68     while(T--) {
69         scanf("%d", &n);
70         Matrix A;
71         A.r = A.c = 3;
72         A.m[1][1] = 2; A.m[1][2] = 1; A.m[1][3] = 0;
73         A.m[2][1] = 2; A.m[2][2] = 2; A.m[2][3] = 2;
74         A.m[3][1] = 0; A.m[3][2] = 1; A.m[3][3] = 2;
75         Matrix B = quickmul(A, n, mod);
76         printf("%d
", B.m[1][1]);
77     }
78     return 0;
79 }
原文地址:https://www.cnblogs.com/kirai/p/5937634.html