Description
某天,幼儿园学生LZH周测数学时吓哭了,一道题都做不出来。这下可麻烦了他马上就会成为垫底的0分啊。他的期望也不高,做出最简单的第一题就够了
题目是这样的,定义F(n)=((根号5+1)/2)^(n-1) ,当然为了凸显题目的简单当然不能是小数分数或无理数,F(x)因此需要向上取整,当然求F(n)是非常难的!因此幼儿园园长头皮决定简单一点,求下F(x)的前n项和就行了。
Input
输入 一个正整数n(保证1<=n<=2^31-1)
Output
输出 一个正整数S(n) 对1000000007 取余就好了
Sample Input
样例输入1
1
样例输入2
2
Sample Output
样例输出1
1
样例输出2
2
Tips
暴力找规律
解题思路
题目不太完整,公式是这个
也就是斐波那契数列和的通项式
和之前一道例题一模一样
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);
B = B * Ac;
printf ("%lld", B.aed[1][1] - 1);
}