1. 程式人生 > >斐波那契數列第N項f(N)[矩陣快速冪]

斐波那契數列第N項f(N)[矩陣快速冪]

string sin int code char const mat ret truct

矩陣快速冪

  定義矩陣A(m*n),B(p*q),A*B有意義當且僅當n=p。即A的列數等於B的行數。

  且C=A*B,C(m*q)。

  例如:

技術分享

  進入正題,由於現在全國卷高考不考矩陣,也沒多大了解。因為遇到了斐波那契這題...

  註意到: Fn+1=Fn+Fn-1

  我們會有:

技術分享

  則:

技術分享

  所以我們只需要想辦法求矩陣A的冪,這時候我們當然想要用快速冪。


代碼部分:

定義矩陣:

struct matrix{
    ll a[3][3];
};

(類比整數的快速冪)預處理:

[我們需要一類似於1的矩陣:]

『1 0 0

0 1 0

0 0 1』類似這種操作...

void init(){
        int i,j;
        memset(res.a,0,sizeof res.a);
        for(i=1;i<=2;i++) res.a[i][i]=1;
        base.a[1][1]=1;
        base.a[1][2]=1;
        base.a[2][1]=1;
        base.a[2][2]=0;
}

矩陣乘法:[就該題而言]

matrix mul(matrix p,matrix q){
        int i,j,k;
        matrix m;
        memset(m.a,
0,sizeof m.a); for(i=1;i<=2;i++) for(j=1;j<=2;j++) for(k=1;k<=2;k++) m.a[i][j]=(m.a[i][j]+p.a[i][k]*q.a[k][j])%Mod; return m; }

快速冪:

void mfpow(ll p){
        init();
        while(p){
            if(p&1) res=mul(base
,res); base=mul(base,base); p>>=1; } }

全部的代碼:(lowbee的難免會差一些,請大佬們見諒...)

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 typedef long long ll ;
 6 inline ll read();
 7 const ll Mod = 1e9 + 7 ;
 8 struct matrix{
 9     ll a[3][3];
10 };
11 matrix res,base;
12 ll ans;
13 ll c[3];
14 ll n;
15 namespace lys{
16     void init(){
17         int i,j;
18         memset(res.a,0,sizeof res.a);
19         for(i=1;i<=2;i++) res.a[i][i]=1;
20         base.a[1][1]=1;
21         base.a[1][2]=1;
22         base.a[2][1]=1;
23         base.a[2][2]=0;
24     }
25     matrix mul(matrix p,matrix q){
26         int i,j,k;
27         matrix m;
28         memset(m.a,0,sizeof m.a);
29         for(i=1;i<=2;i++)
30             for(j=1;j<=2;j++)
31                 for(k=1;k<=2;k++)
32                     m.a[i][j]=(m.a[i][j]+p.a[i][k]*q.a[k][j])%Mod;
33         return m;
34     }
35     void mfpow(ll p){
36         init();
37         while(p){
38             if(p&1) res=mul(base,res);
39             base=mul(base,base);
40             p>>=1;
41         } 
42     }
43     int main(){
44         int k;
45         n=read();
46         mfpow(n-1);
47         c[1]=1;
48         c[2]=0;
49         for(k=1;k<=2;k++)
50             ans=(ans+res.a[1][k]*c[k])%Mod;    
51         cout<<ans<<endl;    
52         return 0;    
53     }
54 }
55 int main(){
56     lys::main();
57     return 0;
58 }
59 inline ll read(){
60     ll k=0,f=1;
61     char c=getchar();
62     while(c<0||c>9){
63         if(c==-)
64             f=-1;
65         c=getchar();
66     }
67     while(c>=0&&c<=9){
68         k=k*10+c-0;
69         c=getchar();
70     }
71     return k*f;
72 }

題目鏈接[luogu]:

https://www.luogu.org/problem/show?pid=1962

斐波那契數列第N項f(N)[矩陣快速冪]