版权声明:本文为博主原创文章,未经博主允许不得转载。 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]);
}