51nod:1242 斐波那契数列的第N项

本文介绍了一种高效计算斐波那契数列的方法,适用于大整数情况。利用矩阵快速幂运算来解决传统递推方法在面对极大数值时效率低下的问题,通过具体示例展示了算法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

斐波那契数列的定义如下:

F(0) = 0
F(1) = 1
F(n) = F(n - 1) + F(n - 2) (n >= 2)

(1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, ...)
给出n,求F(n),由于结果很大,输出F(n) % 1000000009的结果即可。
Input
输入1个数n(1 <= n <= 10^18)。
Output
输出F(n) % 1000000009的结果。
Input示例
11
Output示例
89


题意很简单,斐波那契数列我们都很熟悉吧!f1=1 f2=1 然后后面的每一项都等于前两项的和,这便是斐波那契数列。

一般我们可以对斐波那契数列线性打表,时间复杂度为O(n)。

但在这道题目中,数据范围为[1,10^18],这样的话,线性的时间复杂度到这时候也会超时啦!


其实,斐波那契数还有一种求法。也就是通过矩阵的乘法,二阶矩阵 (1 1 1 0) 可以经过幂次运算,然后得到相应第多少个斐波那契数,而在幂次运算中,我们可以采用快速幂运算,不会超时的矩阵连乘哦!


AC代码:

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <queue>
using namespace std;
const __int64 mod=1000000009;
struct node
{
    __int64 mp[2][2];
    void init(__int64 a,__int64 b,__int64 c,__int64 d)
    {
        mp[0][0]=a;
        mp[0][1]=b;
        mp[1][0]=c;
        mp[1][1]=d;
    }
    void mult(node x,node y)                //两矩阵乘法
    {
        memset(mp,0,sizeof(mp));
        for(__int64 i=0; i<2; i++)
            for(__int64 j=0; j<2; j++)
                for(__int64 k=0; k<2; k++)
                    mp[i][j]=(mp[i][j]+x.mp[i][k]*y.mp[k][j])%mod;
    };
} init;

struct node expo(struct node x, __int64 k)  //进行k次幂运算
{
    struct node tmp;
    tmp.init(1,0,0,1);                      //单位矩阵
    while(k)                                //快速幂部分
    {
        if(k&1)tmp.mult(tmp,x);
        x.mult(x,x);
        k>>=1;
    }
    return tmp;
}
int main()
{
    __int64 k;
    scanf("%I64d",&k);
    init.init(1,1,1,0);     //初始化矩阵(1 1 1 0)
    printf("%I64d\n",expo(init,k).mp[0][1]%mod);
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值