题目描述
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;
.
.
.
.
.
.
分析
.
.
.
.
.
.
.
程序:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
long long mo=1000000007,ans[3][3],a[3][3];
void jzcf(long long x[3][3],long long y[3][3])
{
long long t[3][3];
memset(t,0,sizeof(t));
for (int i=0;i<=2;i++)
for (int j=0;j<=2;j++)
for (int k=0;k<=2;k++)
t[i][j]=((long long)x[i][k]*y[k][j]%mo+t[i][j]+mo)%mo;
for (int i=0;i<=2;i++)
for (int j=0;j<=2;j++)
x[i][j]=t[i][j];
}
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
long long n;
scanf("%lld",&n);
if (n<=3)
{
printf("1\n");
continue;
}
memset(ans,0,sizeof(ans));
memset(a,0,sizeof(a));
ans[0][0]=a[0][0]=1;ans[0][1]=a[0][1]=0;ans[0][2]=a[0][2]=1;
ans[1][0]=a[1][0]=1;ans[1][1]=a[1][1]=0;ans[1][2]=a[1][2]=0;
ans[2][0]=a[2][0]=0;ans[2][1]=a[2][1]=1;ans[2][2]=a[2][2]=0;
n--;
while (n!=0)
{
if (n&1) jzcf(ans,a);
jzcf(a,a);
n>>=1;
}
printf("%lld\n",(ans[1][0]+mo)%mo);
}
return 0;
}