矩阵快速幂&利用矩阵快速幂求斐波那契数列第n项

牛客第一场J题让我明白了自己有多少东西都还不会,今天来学习一下神(jian)奇(dan)的矩阵快速幂并如何利用矩阵快速幂求斐波那契数列第n项(n>1e10)

先上代码:

#include <iostream>
#include <cstring>
#include <string>
#define ll long long
#define mod 1000000007
using namespace std;
struct node {
    ll a[2][2];
    void init_1()                    //1 1
    {                                //0 0
        a[0][0] = a[0][1] = 1;
        a[1][0] = a[1][1] = 0;
    }

    void init_2()                     //1 1
    {                                 //1 0
        a[0][0] = a[0][1] = a[1][0] = 1;
        a[1][1] = 0;
    }

    void init_3()                     //1 0
    {                                 //0 1
        a[0][0] = a[1][1] = 1;
        a[0][1] = a[1][0] = 0;
    }

    friend ll getfabo(node a,node b,ll n)
    {
        if (n == 1)
            return 1;
        a.init_1();
        b.init_2();
        b = qmul(b,n-2);
        a = mul(a, b);
        return a.a[0][0];
    }

    friend node mul(node a,node b)//朴实无华的矩阵乘法
    {
        node ans;
        for (int i = 0; i < 2; i++)
        {
            for (int j = 0; j < 2; j++)
            {
                ans.a[i][j] = 0;
                for (int k = 0; k < 2; k++)
                {
                    ans.a[i][j] = (ans.a[i][j] + (a.a[i][k] * b.a[k][j] % mod)) % mod;
                }
            }
        }
        return ans;
    }

    friend node qmul(node a, ll n)//(神奇而简单的矩阵快速幂)和快速幂原理一样
    {
        node b;
        b.init_3();
        while (n)
        {
            if (n & 1)
                b = mul(a, b);
            n >>= 1;
            a = mul(a, a);
        }
        return b;
    }

}fabo1,fabo2;

int main()
{
    cout << getfabo(fabo1, fabo2, 1000000000000)<<endl;
    return 0;
}

简单证明:

在这里插入图片描述

以上就是矩阵快速幂&斐波那契第n项的板子…

发布了30 篇原创文章 · 获赞 9 · 访问量 1303

猜你喜欢

转载自blog.csdn.net/Zhang_sir00/article/details/104193435