模板:矩阵快速幂(斐波那契数列)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了模板:矩阵快速幂(斐波那契数列)相关的知识,希望对你有一定的参考价值。

洛谷P1962 斐波那契数列

题目背景

大家都知道,斐波那契数列是满足如下性质的一个数列:

• 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)范围内。

首先看到数据范围,longlong以内,故我们考虑矩阵加速动态规划。

我们都知道斐波那契数列有这样的一个动态转移方程:f[i]=f[i-1]+f[i-2];

由此可以推出一个2×2的矩阵:1 1 1 0

然后就是套用矩阵快速幂的模板来加速。

以下是代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cstdlib>
using namespace std;
typedef long long lol;

lol n;
lol mod=1e9+7;
lol f[3][3],ans[3]={0,1,1};

void lu() {
lol t[3]={0};
for (int i=1;i<=2;i++)
for (int j=1;j<=2;j++)
t[i]=(t[i]+(ans[j]*f[j][i])%mod)%mod;
memcpy(ans,t,sizeof(ans));
}

void ge() {
lol t[3][3]={0};
for (lol i=1;i<=2;i++)
for (lol j=1;j<=2;j++)
for (lol k=1;k<=2;k++)
t[i][j]=(t[i][j]+(f[i][k]*f[k][j])%mod)%mod;
memcpy(f,t,sizeof(f));
}

int main() {
cin>>n;
if (n==1||n==2||!n) {
cout<<‘1‘<<endl;
exit(0);
}
n--;
f[1][1]=1;f[1][2]=1;
f[2][1]=1;f[2][2]=0;
while (n) {
if (n&1) lu();
ge();n>>=1;
}
cout<<ans[2]<<endl;
return 0;
}

技术分享图片

以上是关于模板:矩阵快速幂(斐波那契数列)的主要内容,如果未能解决你的问题,请参考以下文章

快速求斐波那契数列(矩阵乘法+快速幂)

[P1962] 斐波那契数列 (矩阵快速幂)

斐波那契数列以及斐波那契数列的衍生形式 利用矩阵快速幂求解

HDU 4549 M斐波那契数列(矩阵快速幂&费马小定理)

[luoguP1962] 斐波那契数列(矩阵快速幂)

斐波那契数列第N项f(N)[矩阵快速幂]