题目描述
a[1]=a[2]=a[3]=1
a[x]=a[x-3]+a[x-1] (x>3)
求a数列的第n项对1000000007(10^9+7)取余的值。
输入输出格式
输入格式:
第一行一个整数T,表示询问个数。
以下T行,每行一个正整数n。
输出格式:
每行输出一个非负整数表示答案。
输入输出样例
输入样例#1:
3
6
8
10
输出样例#1:
4
9
19
说明
对于30%的数据 n<=100;
对于60%的数据 n<=2*10^7;
对于100%的数据 T<=100,n<=2*10^9;
/*
0 1 0
0 0 1
1 0 1 该矩阵自乘n-4遍 最后 乘以矩阵 1
1
1
*/
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
using namespace std;
#define Mod 1000000007
#define LL long long
LL A[4][4],B[4][4],C[4][4];
int T,n;
void Mul(LL a[4][4],LL b[4][4]){
LL c[4][4];
memset(c,0,sizeof c );
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
for(int k=1;k<=3;k++)
c[i][j]=(c[i][j]+a[i][k]*b[k][j])%Mod;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
a[i][j]=c[i][j];
}
int main(){
scanf("%d",&T);
while(T--){
memset(A,0,sizeof A );memset(B,0,sizeof B );
memset(C,0,sizeof C );
A[1][2]=1;A[2][3]=1;A[3][1]=1;A[3][3]=1;
C[1][2]=1;C[2][3]=1;C[3][1]=1;C[3][3]=1;
B[1][1]=1;B[2][1]=1;B[3][1]=1;
scanf("%d",&n);
if(n<=3){ printf("1\n");continue; }
n-=3;n--;//n-- 是因为 刚开始让C=A了
while(n){
if(n&1) Mul(C,A);
Mul(A,A); n>>=1;
}
LL D[4][4];
memset(D,0,sizeof D );
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
for(int k=1;k<=3;k++)
D[i][j]=(D[i][j]+C[i][k]*B[k][j])%Mod;
printf("%lld\n",D[3][1]);
}
}