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

洛谷 1939

a[1]=a[2]=a[3]=1

a[x]=a[x-3]+a[x-1] (x>3)

求a数列的第n项对1000000007(10^9+7)取余的值。

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #define LL long long
 5 #define rg register
 6 #define N 100
 7 #define n 3
 8 using namespace std;
 9 const LL Mod=1e9+7;
10 LL T,m,tmp[N][N];
11 struct Mat{LL m[N][N];}t,ans;
12 inline LL read(){
13     LL k=0; char c=getchar();
14     while(c<'0'||c>'9')c=getchar();
15     while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar();
16     return k;
17 }
18 inline void mul(Mat &a,Mat b){
19     for(rg int i=1;i<=n;i++)
20     for(rg int j=1;j<=n;j++) 
21     for(rg int k=1;k<=n;k++)
22     tmp[i][j]+=a.m[i][k]*b.m[k][j],tmp[i][j]%=Mod;
23     for(rg int i=1;i<=n;i++)
24     for(rg int j=1;j<=n;j++) a.m[i][j]=tmp[i][j],tmp[i][j]=0;
25 }
26 int main(){
27     T=read();
28     while(T--){
29         memset(t.m,0,sizeof(t.m));
30         memset(ans.m,0,sizeof(ans.m));
31         t.m[1][1]=1; t.m[1][3]=1; t.m[2][1]=1; t.m[3][2]=1;
32         for(rg int i=1;i<=n;i++) ans.m[i][i]=1;
33         m=read();
34         if(m<=3){
35             puts("1"); continue;
36         }
37         m-=3;
38         while(m){
39             if(m&1) mul(ans,t); mul(t,t); m>>=1;
40         }
41         printf("%lld\n",(ans.m[1][1]+ans.m[1][2]+ans.m[1][3])%Mod);
42     }
43     return 0;
44 }
View Code

 

posted @ 2018-04-18 16:48  Driver_Lao  阅读(232)  评论(0编辑  收藏  举报