题目描述
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,0,0}
{0,1,0}
{1,0,1}
矩阵快速幂即可
代码:
// luogu-judger-enable-o2 #include<iostream> #include<cstdio> #include<cstring> #define mod 1000000007 #define rii register int i #define rij register int j #define rik register int k using namespace std; struct j{ long long jz[5][5]; }x,y,z; long long n,t; j cheng(j l,j r) { j an; memset(an.jz,0,sizeof(an.jz)); long long ans=0; for(rii=1;i<=3;i++) { for(rij=1;j<=3;j++) { ans=0; for(rik=1;k<=3;k++) { ans+=(l.jz[i][k]*r.jz[k][j]); ans%=mod; } an.jz[i][j]=ans; } } return an; } void pw(j k,long long c) { if(c==1) { y=cheng(k,y); return; } if(c%2==1) { c--; y=cheng(y,k); pw(k,c); } else { k=cheng(k,k); pw(k,c/2); } } int main() { cin>>t; while(t--) { cin>>n; if(n<=3) { cout<<1<<endl; continue; } memset(x.jz,0,sizeof(z.jz)); memset(y.jz,0,sizeof(y.jz)); y.jz[1][1]=1; y.jz[2][2]=1; y.jz[3][3]=1; x.jz[1][1]=1; x.jz[1][2]=1; x.jz[3][1]=1; x.jz[2][3]=1; pw(x,n-1); cout<<y.jz[1][1]<<endl; } }