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

题目大意:

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

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

求a数列的第n项%1000000007

思路:

使用矩阵快速幂进行加速

在草稿纸上填了填数

然后就A了

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstdlib>
 5 #include<cstring>
 6 #include<algorithm>
 7 #include<map>
 8 #include<vector>
 9 #include<queue>
10 #define inf 2147483611
11 #define ll long long
12 #define MAXN 10010000
13 #define MOD 1000000007
14 using namespace std;
15 inline ll read()
16 {
17     ll x=0,f=1;char ch=getchar();
18     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
19     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
20     return x*f;
21 }
22 ll T,n;
23 struct mat {ll num[3][3];};
24 mat mul (mat x,mat y)
25 {
26     mat res;
27     memset(res.num,0,sizeof(res.num));
28     for(ll i=0;i<3;i++)
29         for(ll j=0;j<3;j++)
30             for(ll k=0;k<3;k++) (res.num[i][j]+=x.num[i][k]*y.num[k][j])%=MOD;
31     return res;
32 }
33 ll q_pow(ll n)
34 {
35     if(n<=3) return 1;
36     n-=3;
37     mat t,res;
38     t.num[0][0]=t.num[0][1]=t.num[1][2]=t.num[2][0]=1,t.num[0][2]=t.num[1][0]=t.num[1][1]=t.num[2][1]=t.num[2][2]=0;
39     res.num[0][0]=res.num[0][1]=res.num[0][2]=res.num[1][0]=res.num[1][1]=res.num[1][2]=res.num[2][0]=res.num[2][1]=1,res.num[2][2]=0;
40     while(n)
41     {
42         //cout<<n<<" "<<res.num[0][0]<<" "<<res.num[0][1]<<" "<<res.num[0][2]<<endl;
43         if(n&1) res=mul(res,t);
44         t=mul(t,t);
45         n>>=1;
46     }
47     return res.num[0][0];
48 }
49 int main()
50 {
51     T=read();
52     while(T--) {n=read();printf("%lld\n",q_pow(n));}
53 }
View Code

 

posted @ 2017-11-27 19:19  jack_yyc  阅读(176)  评论(0编辑  收藏  举报