首页 > 代码库 > 【模板】矩阵加速(数列)

【模板】矩阵加速(数列)

题目描述

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 } 

 

【模板】矩阵加速(数列)