【矩阵专题】——矩阵加速

今天来讲矩阵加速:

  例题:https://www.luogu.org/problemnew/show/P1939

  如果一个个去求就会T掉,所以我们使用矩阵加速。

  矩阵加速是用来解决一些与递推式有关的问题,形如f(x)=a(x)p1+a(x-1)p2+……+a(x-k)pk(已知几个初项)

 我们可以建立一个矩阵:

 

 这个时候,我们发现中间那一个数字组成的矩阵会重复多次计算,这个过程可以用矩阵快速幂解决。

因此,对于,我们可以:

 

用快速幂解决中间部分,最后与初项相乘,可得到an。

这个推理的部分,可以尝试在纸上解决。

上代码:

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 ll n,num,answer;
 5 const ll mod=1e9+7;
 6 struct matrix{
 7     ll a[5][5];
 8     void Empty(){
 9         memset(a,0,sizeof(a));
10     }
11     void One(){
12         Empty();
13         for(int i=1;i<=3;i++) a[i][i]=1;
14     }
15     void reset(){
16         Empty();
17         a[1][1]=a[1][3]=a[2][1]=a[3][2]=1;
18     }
19     matrix operator*(matrix b){
20         matrix tmp;
21         tmp.Empty();
22         for(int i=1;i<=3;i++){
23             for(int j=1;j<=3;j++){
24                 for(int k=1;k<=3;k++){
25                     (tmp.a[i][j]+=a[i][k]*b.a[k][j]%mod)%=mod;
26                 }
27             }
28         }
29         return tmp;
30     }
31 }res,ans;
32 void pow(ll p){
33     res.reset();
34     ans.One();
35     while(p){
36         if(p&1){
37             ans=ans*res;
38         }
39         res=res*res;
40         p>>=1;
41     }
42 }
43 int main(){
44     cin>>n;
45     for(int i=1;i<=n;i++){
46         cin>>num;
47         if(num<4){
48             cout<<1<<endl;
49             continue;
50         }
51         pow(num-3);
52         answer=(ans.a[1][1]%mod+ans.a[2][1]%mod+ans.a[3][1]%mod)%mod;
53         cout<<answer<<endl;
54     }
55     return 0;
56 }

 

 

 

posted @ 2019-07-08 15:05  Nelson992770019  阅读(223)  评论(0编辑  收藏  举报