POJ 3734 Blocks
矩阵快速幂。
设ai表示涂完i块之后,红绿均为偶数的方案数
设bi表示涂完i块之后,红为偶数的方案数
设ci表示涂完i块之后,绿为偶数的方案数
设di表示涂完i块之后,都不是偶数的方案数
ai+1=ai+ai+bi+ci
bi+1=ai+2*bi+di
ci+1=ai+2*ci+di
di+1=bi+ci+2*di
然后很容易构造出矩阵。
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> using namespace std; int n; long long MOD=10007; struct Matrix { long long A[5][5]; int R, C; Matrix operator*(Matrix b); }; Matrix X, Y, Z; Matrix Matrix::operator*(Matrix b) { Matrix c; memset(c.A, 0, sizeof(c.A)); int i, j, k; for (i = 1; i <= R; i++) for (j = 1; j <= b.C; j++) for (k = 1; k <= C; k++) c.A[i][j] = (c.A[i][j] + (A[i][k] * b.A[k][j]) % MOD) % MOD; c.R = R; c.C = b.C; return c; } void init() { n=n-1; memset(X.A, 0, sizeof X.A); memset(Y.A, 0, sizeof Y.A); memset(Z.A, 0, sizeof Z.A); Y.R = 4; Y.C = 4; for (int i = 1; i <= 4; i++) Y.A[i][i] = 1; X.R = 4; X.C = 4; X.A[1][1]=2; X.A[1][2]=1; X.A[1][3]=1; X.A[1][4]=0; X.A[2][1]=1; X.A[2][2]=2; X.A[2][3]=0; X.A[2][4]=1; X.A[3][1]=1; X.A[3][2]=0; X.A[3][3]=2; X.A[3][4]=1; X.A[4][1]=0; X.A[4][2]=1; X.A[4][3]=1; X.A[4][4]=2; Z.R = 1; Z.C = 4; Z.A[1][1]=2; Z.A[1][2]=1; Z.A[1][3]=1; Z.A[1][4]=0; } void read() { scanf("%d", &n); } void work() { while (n) { if (n % 2 == 1) Y = Y*X; n = n >> 1; X = X*X; } Z = Z*Y; printf("%lld\n",Z.A[1][1]); } int main() { int Case=1; int T; scanf("%d", &T); while (T--) { read(); init(); work(); } return 0; }