数列
时间限制: 1 Sec 内存限制: 128 MB
提交: 16 解决: 11
[提交][状态][讨论版]
题目描述
a[1]=a[2]=a[3]=1
a[x]=a[x-3]+a[x-1] (x>3)
求a数列的第n项对1000000007(10^9+7)取余的值。
a[x]=a[x-3]+a[x-1] (x>3)
求a数列的第n项对1000000007(10^9+7)取余的值。
输入
第一行一个整数T,表示询问个数。
以下T行,每行一个正整数n。
以下T行,每行一个正整数n。
输出
每行输出一个非负整数表示答案。
样例输入
3
6
8
10
样例输出
4
9
19
提示
对于30%的数据 n<=100;
对于60%的数据 n<=2*10^7;
对于100%的数据 T<=100,n<=2*10^9;
【分析】矩阵快速幂
#include <cstdio> #include <string> #include <cmath> #include <iostream> using namespace std; const long long M = 1e9+7; const long long N = 3; long long t=1,b=1,c=0,f1=1,f2=1; struct Node { long long line,cal; long long a[N+1][N+1]; Node() { line=3,cal=3; a[0][0] = 1;a[0][1] = 0;a[0][2] = 1; a[1][0] = 1;a[1][1] = 0;a[1][2] = 0; a[2][0] = 0;a[2][1] = 1;a[2][2] = 0; } }; Node isit(Node x,long long c) { for(long long i=0; i<N; i++) for(long long j=0; j<N; j++) x.a[i][j]=c; return x; } Node Matlab(Node x,Node s) { Node ans; ans.line = x.line,ans.cal = s.cal; ans=isit(ans,0); for(long long i=0; i<x.line; i++) { for(long long j=0; j<x.cal; j++) { for(long long k=0; k<s.cal; k++) { ans.a[i][j] += x.a[i][k]*s.a[k][j]; ans.a[i][j]=(ans.a[i][j]+M)%M; } } } return ans; } long long Fast_Matrax(long long n) { if(n==1) return f1; n-=2; long long x=1,f=n,ok=1; Node ans,tmp,ch; ans.line = 1,ans.cal = 3; ans.a[0][0] = f2, ans.a[0][1] = f1,ans.a[0][2] = 1; while(n>0) { if(n%2) { ans=Matlab(ans,tmp); } tmp=Matlab(tmp,tmp); n/=2; } return ans.a[0][0]; } int main() { long long n,T; scanf("%lld",&T); while(T--) { scanf("%lld",&n); printf("%lld ",Fast_Matrax(n-1)); } return 0; }