题解:
若当前有i个格子。
2个是偶数的方案数为a[i]
1个是偶数的方案数为b[i]
0个是偶数的方案数为c[i]
a[i+1]=2*a[i](i+1染成黄或蓝)+b[i](把奇数变为偶数)
b[i+1]=2*a[i](把某个偶数变为奇数)+2*b[i](i+1染成黄或蓝)+2*c[i](把某个奇数变为偶数)
c[i+1]=b[i](把偶数变为奇数)+2*c[i](i+1染成黄或蓝)
解析式难想,要学会这种分类递推的方法。
然后就可以推出
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> using namespace std; const int N=1000000010,Mod=10007; struct node{ int sx,sy; int s[4][4]; }; node mult(node a,node b) { node c; c.sx=a.sx;c.sy=b.sy; memset(c.s,0,sizeof(c.s)); for(int i=1;i<=a.sx;i++) for(int j=1;j<=b.sy;j++) for(int k=1;k<=a.sx;k++) { c.s[i][j]+=(a.s[i][k]*b.s[k][j])%Mod; c.s[i][j]%=Mod; } return c; } void solve(int x) { node a; a.sx=a.sy=3; a.s[1][1]=2;a.s[1][2]=1;a.s[1][3]=0; a.s[2][1]=a.s[2][2]=a.s[2][3]=2; a.s[3][1]=0;a.s[3][2]=1;a.s[3][3]=2; node b; b.sx=b.sy=3; memset(b.s,0,sizeof(b.s)); for(int i=1;i<=3;i++) b.s[i][i]=1; while(x) { if(x&1) b=mult(b,a); a=mult(a,a); x>>=1; } node c; c.sx=3;c.sy=1; c.s[1][1]=1; c.s[2][1]=c.s[3][1]=0; c=mult(b,c); printf("%d ",c.s[1][1]); return ; } int main() { int T; scanf("%d",&T); while(T--) { int x; scanf("%d",&x); solve(x); } return 0; }