题目描述
求数列 f n = f n − 2 + f n − 1 f_n=f_{n-2}+f_{n-1} fn=fn−2+fn−1 的前 n n n 项的和,其中 f 1 = 1 , f 2 = 1 f_1=1,f_2=1 f1=1,f2=1。 输出的数 m o d 1 0 9 + 7 \bmod\ 10^9+7 mod 109+7
输入格式
一个数 n n n。
输出格式
前 n n n 项和 m o d 1 0 9 + 7 \bmod\ 10^9+7 mod 109+7
输入输出样例
输入 #1
10
输出 #1
143
输入 #2
1234567
输出 #2
624628108
说明/提示
【数据范围】
对于 20 % 20\% 20% 的数据,有 1 ≤ n ≤ 20 1\leq n\leq 20 1≤n≤20
对于 100 % 100\% 100% 的数据,有 1 ≤ n < 2 63 1≤n<2^{63} 1≤n<263
解题思路
设前 n n n项的和为 s [ n ] s[n] s[n]
众所周知, s [ n ] = f [ n + 2 ] − 1 s[n] = f[n + 2] - 1 s[n]=f[n+2]−1
f [ n + 2 ] − 1 f[n + 2] - 1 f[n+2]−1
= f [ n ] + f [ n + 1 ] − 1 = f[n] + f[n + 1] - 1 =f[n]+f[n+1]−1
= f [ n ] + f [ n − 1 ] + f [ n ] − 1 = f[n] + f[n - 1] + f[n] - 1 =f[n]+f[n−1]+f[n]−1
= f [ n ] + f [ n − 1 ] + f [ n − 2 ] + f [ n − 1 ] − 1 = f[n] + f[n - 1] + f[n - 2] + f[n - 1] - 1 =f[n]+f[n−1]+f[n−2]+f[n−1]−1
= f [ n ] + f [ n − 1 ] + . . . + f [ 2 ] + f [ 1 ] + f [ 2 ] − 1 = f[n] + f[n - 1] + ... +f[2] + f[1] + f[2]- 1 =f[n]+f[n−1]+...+f[2]+f[1]+f[2]−1
∵ f [ 2 ] = 1 ∵f[2] = 1 ∵f[2]=1
∴ f [ n + 2 ] = f [ n ] + f [ n − 1 ] + . . . + f [ 1 ] = s [ n ] ∴f[n + 2] = f[n] + f[n-1] + ... +f[1] = s[n] ∴f[n+2]=f[n]+f[n−1]+...+f[1]=s[n]
用矩阵乘法算出 f [ n + 2 ] f[n + 2] f[n+2]
详情请见裴波拉契数列II
Code
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int Mod = 1000000007;
long long n;
struct DT{
int n, m;
long long aed[5][5];
}A, B, Ac;
DT operator *(DT a, DT b){
//矩阵乘法
DT c;
c.n = a.n, c.m = b.m;
memset (c.aed, 0, sizeof (c.aed));
for (int k = 1; k <= a.m; k++)
for (int i = 1; i <= c.n; i++)
for (int j = 1; j <= c.m; j++)
c.aed[i][j] = (c.aed[i][j] + a.aed[i][k] * b.aed[k][j] % Mod) % Mod;
return c;
}
void power (long long n){
//快速幂
if (n == 1)
{
Ac = A;
return;
}
power (n / 2);
Ac = Ac * Ac;
if (n % 2) Ac = Ac * A;
}
int main(){
A.n = A.m = 2;
A.aed[1][2] = A.aed[2][1] = A.aed[2][2] = 1;
B.n = 1, B.m = 2;
B.aed[1][1] = B.aed[1][2] = 1;
scanf ("%lld", &n);
power (n + 1);//A ^ (n + 1) * B = 第n + 2项
B = B * Ac;
printf ("%lld", B.aed[1][1] - 1);
}