1. 程式人生 > >用矩陣快速冪求斐波那契數列

用矩陣快速冪求斐波那契數列

在學習矩陣快速冪之前,先要知道快速冪,大家可以通過這個網址初步瞭解快速冪
http://blog.csdn.net/ffgcc/article/details/78012628
瞭解過之後我們來學習矩陣快速冪.
先了解一下矩陣乘法:
若A為n×k矩陣,B為k×m矩陣,則它們的乘積AB(有時記做A·B)將是一個n×m矩陣。前一個矩陣的列數應該等於後一個矩陣的行數,得出的矩陣行數等於前一個矩陣的行數,列數等於後一個矩陣的行數。
其乘積矩陣AB的第i行第j列的元素為:
這裡寫圖片描述
二階矩陣相乘的程式碼為:

struct node
{
    ll m,l;//m為矩陣的行數,l為矩陣的列數
    ll v[3
][3]; }; node get_mul(node a,node b) { node c; c.m=a.m,c.l=b.l; for(int i=1;i<=c.m;i++) { for(int j=1;j<=c.l;j++) { c.v[i][j]=0; for(int k=1;k<=a.l;k++) { c.v[i][j]=(c.v[i][j]+a.v[i][k]*b.v[k][j])%mod; } } } return
c; }

矩陣和斐波那契數列之間的關係:
斐波那契的公式為f[n]=f[n-1]+f[n-2],
則f[n]=1 * f[n-1]+1 * f[n-2],f[n-1]=1 * f[n-1]+0 * f[n-2]
這裡寫圖片描述
將矩陣相乘與快速冪相結合我們可以寫出快速求得f[n]的程式碼

int getresult(ll n)
{
    node a,b;
    a.l=2,a.m=1,a.v[1][1]=1,a.v[1][2]=0;
    b.l=2,b.m=2,b.v[1][1]=1,b.v[1][2]=1,b.v[2][1]=1,b.v[2][2]=0;
    while(n)
    {
        if
(n&1) a=get_mul(a,b); b=get_mul(b,b); n/=2; } return a.v[1][2]; }

主函式為

int main()
{
    ios::sync_with_stdio(false);
    ll n;
    while(cin>>n)
    {
        if(n==-1)
            break;
        cout<<getresult(n)<<endl;
    }
    return 0;
}