小L是一个可爱的女孩,她特别喜欢玩多米诺骨牌。有一天她得到了一个宽度为2长度为n的棋盘。她现在有1*2大小的矩形骨牌和3格大小的L型骨牌(L型骨牌的样式参考Hint)。她发现有很多种方式可以让这个棋盘完全覆盖,她想知道对于每一个2*n大小的棋盘,用这两种骨牌完全覆盖的方案数。这个数字可能很大,所以答案需要模1000000007.
输入数据第一行为T,代表数据组数。
接下来的T行中,每一行只有一个数字n,n为不超过1e18的正整数,代表棋盘的长度。
输出T行,每行为对应n的答案。
1
2
2
#include
#define ll long long
const int MOD = 1000000007;
const int N = 3;
struct Matrix {
ll mat[N][N];
Matrix operator*(const Matrix& m)const {
Matrix tmp;
for (ll i = 0 ; i < N ; i++) {
for (ll j = 0 ; j < N ; j++) {
tmp.mat[i][j] = 0;
for (ll k = 0 ; k < N ; k++)
tmp.mat[i][j] = (tmp.mat[i][j] + mat[i][k]*m.mat[k][j])%MOD;
tmp.mat[i][j] %= MOD;
}
}
return tmp;
}
};
Matrix m;
int T;
ll n;
ll Pow(ll n) {
n-=2;
Matrix k,ans,e;
k.mat[0][0]=1; k.mat[0][1]=1; k.mat[0][2]=2;//f[i]=f[i-1]+f[i-2]+2*g[i-3]
k.mat[1][0]=1; k.mat[1][1]=0; k.mat[1][2]=0;//f[i-1]=f[i-1]
k.mat[2][0]=0; k.mat[2][1]=1; k.mat[2][2]=1;//g[i-2]=f[i-2]+g[i-3]
for (int i=0;ifor (int j=0;j0;
ans.mat[0][0]=2;//f2=2
ans.mat[1][0]=1;//f1=1
ans.mat[2][0]=1;//g0=1
for (int i=0;i1;
while (n) {
if (n&1) e = e*k;
k=k*k;
n>>=1;
}
ans=e*ans;
return ans.mat[0][0]%MOD;
}
int main() {
scanf("%d",&T);
while (T--) {
scanf("%lld",&n);
if (n==0) printf("1\n");
else if (n==1) printf("1\n");
else if (n==2) printf("2\n");
else printf("%lld\n",Pow(n));
}
return 0;
}