题目描述
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> #include<algorithm> using namespace std; typedef long long ll; const int mod=1e9+7; inline ll read(){ ll x=0,f=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } struct mat { ll m[6][6]; int x,y; }a,b; inline mat matmul(mat x,mat y){ mat t; t.x=x.y; t.y=y.y; for(int i=1;i<=x.x;++i) for(int j=1;j<=y.y;++j){ t.m[i][j]=0; for(int k=1;k<=x.y;++k) t.m[i][j]=(t.m[i][j]+x.m[i][k]*y.m[k][j])%mod; } return t; } inline mat matpow(mat x,int p){ mat res; res.x=res.y=3; for(int i=1;i<=3;++i) for(int j=1;j<=3;++j) res.m[i][j]=x.m[i][j]; while(p){ if(p&1) res=matmul(res,x); x=matmul(x,x); p=p>>1; } return res; } int main() { int T=read(),n; a.m[1][1]=a.m[1][3]=a.m[2][1]=a.m[3][2]=1; b.m[1][1]=b.m[2][1]=b.m[3][1]=1; a.x=a.y=3; b.x=3; b.y=1; while(T--){ n=read(); if(n<=3) {printf("%d ",1); continue;} mat tmp=matpow(a,n-3-1); tmp=matmul(tmp,b); printf("%lld ",tmp.m[1][1]); } return 0; }