这里需要使用矩阵快速幂(斐波那契数列的项数n一旦过大,就要考虑矩阵快速幂)。
使用矩阵快速幂的一个关键问题就是矩阵递推式。
可以得到下面这个递推式了:
我用等式 T^(n+1)=B*T^n,来代替上面的等式
计算矩阵B得到如图矩阵:
所以T^n=B^(n-1)*T
这样直接使用矩阵快速幂计算B^(n-1),再B^(n-1)的第一行乘T的第一列,得到 A[n]
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll mat[][6]={
{1, 1, 1, 1, 1, 1},
{1, 0, 0, 0, 0, 0},
{0, 0, 1, 3, 3, 1},
{0, 0, 0, 1, 2, 1},
{0, 0, 0, 0, 1, 1},
{0, 0, 0, 0, 0, 1}
};
ll res[6][6];
ll now[6][6];
int A[]={1, 0, 8, 4, 2, 1};
void mul(ll a[][6],ll b[][6]){
ll c[6][6];
memset(c,0,sizeof(c));
for(int i=0;i<6;i++){
for(int j=0;j<6;j++){
if(a[i][j])
for(int k=0;k<6;k++){
c[i][k]=(c[i][k]+(a[i][j]*b[j][k])%mod)%mod;
}
}
}
for(int i=0;i<6;i++){
for(int j=0;j<6;j++){
a[i][j]=c[i][j];
}
}
}
void mypow(ll n){
memset(res,0,sizeof(res));
for(int i=0;i<6;i++) res[i][i]=1;
for(int i=0;i<6;i++){
for(int j=0;j<6;j++){
now[i][j]=mat[i][j];
}
}
while(n){
if(n&1) mul(res,now);
mul(now,now);
n>>=1;
}
}
int main(){
int T;
scanf("%d",&T);
while(T--){
ll n;
scanf("%lld",&n);
n--;
mypow(n);
ll sum=0;
for(int i=0;i<6;i++){
sum=(sum+res[0][i]*A[i])%mod;
}
printf("%lld\n",sum);
}
}