洛谷P1962 斐波那契数列(矩阵快速幂)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zhanghaoxian1/article/details/82020256

斐波那契数列

题目背景
大家都知道,斐波那契数列是满足如下性质的一个数列:
• f(1) = 1
• f(2) = 1
• f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数)

题目描述
请你求出 f(n) mod 1000000007 的值。

输入输出格式

输入格式:
·第 1 行:一个整数 n

输出格式:
第 1 行: f(n) mod 1000000007 的值

输入输出样例

输入样例#1:
5
输出样例#1:
5
输入样例#2:
10
输出样例#2:
55

说明
对于 60% 的数据: n ≤ 92
对于 100% 的数据: n在long long(INT64)范围内。

分析:f[0]存数列第2项,f[1]存数列第1项,然后矩阵乘法一下就好了。

代码

#include <cstdio>
#include <cstring>
#include <string>
#include <cmath>
#define mo 1000000007
#define ll long long
using namespace std;

ll n;
ll f[2] = {0, 1};
ll a[2][2] = {{0, 1}, {1, 1}};

void mul()
{
    ll c[2];
    c[0] = c[1] = 0;
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 2; j++)
            c[i] = (c[i] + f[j] * a[j][i]) % mo;
    f[1] = c[1];
    f[0] = c[0];
}

void mula()
{
    ll c[2][2];
    memset(c, 0, sizeof(c));
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 2; j++)
            for (int k = 0; k < 2; k++)
                c[i][j] = (c[i][j] + a[i][k] * a[k][j]) % mo;
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 2; j++)
            a[i][j] = c[i][j];
}

int main()
{
    scanf("%lld", &n);
    while (n)
    {
        if (n & 1) mul();
        mula();
        n >>= 1;
    }
    printf("%lld", f[0]);
}

猜你喜欢

转载自blog.csdn.net/zhanghaoxian1/article/details/82020256
今日推荐