数列
题目描述 Description
a[1]=a[2]=a[3]=1
a[x]=a[x-3]+a[x-1] (x>3)
求a数列的第n项对1000000007(10^9+7)取余的值。
输入描述 Input Description
第一行一个整数T,表示询问个数。
以下T行,每行一个正整数n。
输出描述 Output Description
每行输出一个非负整数表示答案
样例输入 Sample Input
3
6
8
10
样例输出 Sample Output
4
9
19
数据范围及提示 Data Size & Hint
对于30%的数据 n<=100;
对于60%的数据 n<=2*10^7;
对于100%的数据 T<=100,n<=2*10^9;
这道题首先一看到n的范围我们就知道暴力是不行的。
所以我们要用一个高级的东西:矩阵乘法。
然后我们推啊推,算啊算(详细过程就上网查矩阵乘法)
具体最后就加成这样(不要嫌我字丑)。
最后在加个快速幂就行了
#include<cstdio>
#include<cstring>
using namespace std;
struct node
{
long long a[5][5];
node()
{
memset(a,0,sizeof(a));
}
};
node pre,f;
node changfa(node a,node b)
{
node c;
for(int i=1;i<=3;i++)
{
for(int j=1;j<=3;j++)
{
for(int k=1;k<=3;k++)
{
c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%1000000007;
}
}
}
return c;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
long long n;
scanf("%lld",&n);
if(n<=3){printf("1\n");continue;}
n-=3;
pre.a[1][1]=pre.a[1][3]=pre.a[2][1]=pre.a[2][2]=pre.a[3][2]=0;
pre.a[1][2]=pre.a[2][3]=pre.a[3][1]=pre.a[3][3]=1;
f.a[1][1]=f.a[2][1]=f.a[3][1]=1;
while(n>0)
{
if(n%2==1) f=changfa(pre,f);
pre=changfa(pre,pre);
n/=2;
}
printf("%lld\n",f.a[3][1]%1000000007);
}
return 0;
}