poj 3420 Quad Tiling
http://poj.org/problem?id=3420
继续矩阵快速幂!
题目意思是给你一个4*n的矩阵用1*2的砖块填充,问有多少种填充的方法。这题可以模仿一道老题(2*n的矩阵用1*2的砖块填充)的递推方法。不过如果是这样递推,推着推着会发现,递推式会有无穷多个项。不过从第三项开始,每项乘以的系数有规律,具体的规律还是查看代码吧!这题我找到的递推式中要分奇偶项,所以构建矩阵的时候就要划分奇偶情况来讨论,所以就构建出奇偶两种矩阵来。奇矩阵是在求奇数项的时候用的,偶矩阵同理。
此题轻松1y,代码如下:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 5 using namespace std; 6 const int maxSize = 5; 7 const int initMod = 1E9 + 7; 8 const int Odd[5][5] = { {1, 1, 0, 0, 0}, 9 {4, 0, 1, 0, 0}, 10 {3, 0, 1, 0, 0}, 11 {2, 0, 0, 1, 0}, 12 {2, 0, 0, 0, 1} }; 13 const int Even[5][5] = { {1, 1, 0, 0, 0}, 14 {4, 0, 0, 1, 0}, 15 {2, 0, 1, 0, 0}, 16 {3, 0, 0, 1, 0}, 17 {3, 0, 0, 0, 1}}; 18 19 int curSize = maxSize; 20 int curMod = initMod; 21 22 struct Matrix { 23 int val[maxSize][maxSize]; 24 25 Matrix (bool ONE = false) { 26 for (int i = 0; i < curSize; i++) { 27 for (int j = 0; j < curSize; j++) { 28 val[i][j] = 0; 29 } 30 if (ONE) val[i][i] = 1; 31 } 32 } 33 34 void print(int _l = maxSize, int _w = maxSize) { 35 for (int i = 0; i < _l; i++) { 36 for (int j = 0; j < _w; j++) { 37 if (j) putchar(' '); 38 printf("%d", val[i][j]); 39 } 40 puts(""); 41 } 42 } 43 } odd, even, Base; 44 45 Matrix operator * (Matrix &_a, Matrix &_b) { 46 Matrix ret = Matrix(); 47 48 for (int i = 0; i < curSize; i++) { 49 for (int k = 0; k < curSize; k++) { 50 if (_a.val[i][k]) { 51 for (int j = 0; j < curSize; j++) { 52 ret.val[i][j] += _a.val[i][k] * _b.val[k][j]; 53 ret.val[i][j] %= curMod; 54 } 55 } 56 } 57 } 58 59 return ret; 60 } 61 62 Matrix operator ^ (Matrix &_a, int _p) { 63 Matrix ret = Matrix(true); 64 Matrix __a = _a; 65 66 while (_p) { 67 if (_p & 1) ret = ret * __a; 68 __a = __a * __a; 69 _p >>= 1; 70 } 71 // puts("yeah!!!"); 72 73 return ret; 74 } 75 76 void initMat() { 77 odd = Matrix(); 78 even = Matrix(); 79 Base = Matrix(); 80 81 for (int i = 0; i < 5; i++) { 82 for (int j = 0; j < 5; j++) { 83 even.val[i][j] = Even[i][j]; 84 odd.val[i][j] = Odd[i][j]; 85 } 86 } 87 Base.val[0][0] = 5; 88 Base.val[0][1] = 1; 89 Base.val[0][4] = 1; 90 // 91 // puts("odd"); 92 // odd.print(); 93 // puts("even"); 94 // even.print(); 95 } 96 97 int deal(int n) { 98 Matrix ans = Base; 99 Matrix TWO = odd * even; 100 101 if (n == 1) return 1 % curMod; 102 if (n == 2) return 5 % curMod; 103 // puts("~~TWO"); 104 // TWO.print(); 105 ans = TWO ^ ((n >> 1) - 1); 106 ans = Base * ans; 107 if (n & 1) ans = ans * odd; 108 // puts("~ans"); 109 // ans.print(); 110 111 return ans.val[0][0]; 112 } 113 114 int main() { 115 int n; 116 117 freopen("in", "r", stdin); 118 initMat(); 119 while (~scanf("%d%d", &n, &curMod) && (n || curMod)) { 120 printf("%d\n", deal(n)); 121 } 122 123 return 0; 124 }
——written by Lyon