码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-12-16 22:07:25      阅读:245      评论:0      收藏:0      [点我收藏+]

标签:range   格式   void   个数   转移   .com   ima   eof   技术   

洛谷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;
}

技术分享图片

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

标签:range   格式   void   个数   转移   .com   ima   eof   技术   

原文地址:http://www.cnblogs.com/fushao2yyj/p/8047700.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!