1.题目描述:点击打开链接
2.解题思路:本题利用矩阵快速幂解决。不妨设Ai表示前i个元素中,红绿均为偶数的方案数;Bi表示前i个中,红绿一奇一偶的方案数;Ci表示前i个方块中,红绿均为奇数的方案数。这样,可以得到如下3个递推式。
A[i+1]=2*A[i]+B[i];
B[i+1]=2*A[i]+2*B[i]+2*C[i];
C[i+1]=B[i]+2*C[i];
将表达式写成矩阵形式,然后自乘n次后,第(0,0)项就是答案。
3.代码:
#include<iostream>
#include<algorithm>
#include<cassert>
#include<string>
#include<sstream>
#include<set>
#include<bitset>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<cctype>
#include<complex>
#include<functional>
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
#define me(s) memset(s,0,sizeof(s))
#define rep(i,n) for(int i=0;i<(n);i++)
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair <int, int> P;
const int MOD=10007;
struct Matrix
{
int m[3][3];
Matrix(){me(m);}
void clear(){me(m);}
void getE()
{
me(m);
for(int i=0;i<3;i++)
m[i][i]=1;
}
Matrix operator*(const Matrix&B)const
{
Matrix res;
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
res.m[i][j]=(res.m[i][j]+m[i][k]*B.m[k][j])%MOD;
return res;
}
Matrix operator^(int d)
{
Matrix res,B=*this;
res.getE();
while(d>0)
{
if(d&1)res=res*B;
B=B*B;
d>>=1;
}
return res;
}
Matrix out()
{
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
printf("%d%c",m[i][j]," \n"[j==2]);
}
};
Matrix A;
void init()
{
A.m[0][0]=2,A.m[0][1]=1,A.m[0][2]=0;
A.m[1][0]=2,A.m[1][1]=2,A.m[1][2]=2;
A.m[2][0]=0,A.m[2][1]=1,A.m[2][2]=2;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
int d;
scanf("%d",&d);
A=A^d;
printf("%d\n",A.m[0][0]);
}
}