幼儿园数学题I
T i m e Time Time L i m i t : 10000 M S Limit:10000MS Limit:10000MS
M e m o r y Memory Memory L i m i t : 65536 K Limit:65536K Limit:65536K
C a s e Case Case T i m e Time Time L i m i t : 1000 M S Limit:1000MS Limit:1000MS
Description
某天,幼儿园学生LZH周测数学时吓哭了,一道题都做不出来。这下可麻烦了他马上就会成为垫底的0分啊。他的期望也不高,做出最简单的第一题就够了
题目是这样的,定义 F ( n ) = ( 根 号 5 + 1 ) / 2 ) n − 1 F(n)=(根号5+1)/2)^{n-1} F(n)=(根号5+1)/2)n−1 ,当然为了凸显题目的简单当然不能是小数分数或无理数, F ( x ) F(x) F(x)因此需要向上取整,当然求 F ( n ) F(n) F(n)是非常难的!因此幼儿园园长头皮决定简单一点,求下 F ( x ) F(x) F(x)的前n项和就行了。
Input
输入 一个正整数n(保证 1 < = n < = 2 31 − 1 1<=n<=2^{31}-1 1<=n<=231−1)
Output
输出 一个正整数 S ( n ) S(n) S(n)对 1000000007 1000000007 1000000007 取余就好了
Sample Input
样例输入1
1
样例输出1
1
样例输入2
2
样例输出2
2
T i p s : Tips: Tips:暴力找规律
分析:
这个样例就很没用 … … …… ……说了跟说了一样 x s w l xswl xswl
还有 题目描述的公式不完整
其实 一看到什么 ( √ 5 + 1 ) / 2 … … (√5+1)/2…… (√5+1)/2……
就能想到 F i b o n a c c i Fibonacci Fibonacci数列通项公式好吧
然后交一波直接过了
百科
完整的为:
所以一个矩阵乘法求前 n n n项之和就可以了(多 s o l v e solve solve)
具体思路: l i n k link link
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int mod=1e9+7;
long long n;
struct matrix{
long long n,m;
long long F[5][5];
}A,B,C;
matrix operator *(matrix x,matrix y)
{
matrix AwA;
AwA.n=x.n;AwA.m=y.m;
for(int i=1;i<=AwA.n;i++)
for(int j=1;j<=AwA.m;j++)
AwA.F[i][j]=0;
for(int k=1;k<=x.m;k++)
for(int i=1;i<=x.n;i++)
for(int j=1;j<=y.m;j++)
AwA.F[i][j]=(AwA.F[i][j]+x.F[i][k]*y.F[k][j]%mod)%mod; //矩阵乘
return AwA;
}
void ksm(long long x){
if(x==1){
B=A;
return;
}
ksm(x/2);
B=B*B; //快速幂
if(x&1) B=B*A;
}
int main(){
scanf("%lld",&n);
A.n=3;A.m=3;
A.F[1][1]=0;A.F[1][2]=1;A.F[1][3]=0;
A.F[2][1]=1;A.F[2][2]=1;A.F[2][3]=1; //初始
A.F[3][1]=0;A.F[3][2]=0;A.F[3][3]=1;
if(n==1){
printf("1");
return 0;
}
else{
C.n=1;C.m=3;
C.F[1][1]=1;C.F[1][2]=1;C.F[1][3]=1;
ksm(n-1);
C=C*B;
printf("%lld",C.F[1][3]);
}
return 0;
}