模板矩阵加速(数列)
Posted Z-Y-Y-S
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板矩阵加速(数列)相关的知识,希望对你有一定的参考价值。
题目描述
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;
题解:
矩阵快速幂:
建出初状态S,再将递推方程表示为T
结果为S*Tn-1。
当前状态(f[i-1],f[i-2],f[i-3])
则递推矩阵为
1 1 0
0 0 1
1 0 0
算出看是不是(f[i],f[i-1],f[i-2])
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 long long Mod=1000000007; 7 struct Matrix 8 { 9 long long a[3][3]; 10 Matrix operator * (const Matrix &x) const{ 11 Matrix ans; 12 memset(ans.a,0,sizeof(ans.a)); 13 for(int i=0;i<=2;++i) 14 for(int j=0;j<=2;++j) 15 for(int k=0;k<=2;++k) 16 (ans.a[i][j]+=a[i][k]*x.a[k][j])%=Mod; 17 return ans; 18 } 19 }; 20 Matrix k; 21 Matrix pow(Matrix x,int p) 22 { 23 Matrix res; 24 res.a[0][0]=1;res.a[0][1]=1;res.a[0][2]=0; 25 res.a[1][0]=0;res.a[1][1]=0;res.a[1][2]=1; 26 res.a[2][0]=1;res.a[2][1]=0;res.a[2][2]=0; 27 while (p) 28 { 29 if (p%2==1) 30 { 31 res=res*k; 32 } 33 k=k*k; 34 p/=2; 35 } 36 return res; 37 } 38 39 int main() 40 {int T,l,n; 41 cin>>T; 42 for (l=1;l<=T;l++) 43 { 44 cin>>n; 45 if (n<=3) 46 { 47 printf("1\n"); 48 } 49 else 50 { 51 52 k.a[0][0]=1;k.a[0][1]=1;k.a[0][2]=0; 53 k.a[1][0]=0;k.a[1][1]=0;k.a[1][2]=1; 54 k.a[2][0]=1;k.a[2][1]=0;k.a[2][2]=0; 55 //{(1,1,0,0),(1,0,1,0),(0,0,0,1),(1,0,0,0)}; 56 Matrix s; 57 s.a[0][0]=1;s.a[0][1]=1;s.a[0][2]=1; 58 s.a[1][0]=0;s.a[1][1]=0;s.a[1][2]=0; 59 s.a[2][0]=0;s.a[2][1]=0;s.a[2][2]=0; 60 //s.a[4][4]={(2,1,1,1),(0,0,0,0),(0,0,0,0),(0,0,0,0)}; 61 s=s*pow(k,n-4); 62 printf("%d\n",s.a[0][0]); 63 } 64 } 65 }
以上是关于模板矩阵加速(数列)的主要内容,如果未能解决你的问题,请参考以下文章