题目描述
求数列 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);
}