您的位置:首页 > 其它

51nod 1358 浮波那契【思维+矩阵快速幂】好题!

2017-01-30 19:01 309 查看
1358 浮波那契

基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题

TengBieBie已经学习了很多关于斐波那切数列的性质,所以他感到一些些厌烦。现在他遇到了一个新的数列,这个数列叫做Float-Bonacci。这里有一个关于Float-Bonacci的定义。



对于一个具体的n,TengBieBie想要快速计算FB(n).

但是TengBieBie对FB的了解非常少,所以他向你求助。

你的任务是计算FB(n).FB(n)可能非常大,请输出FB(n)%1,000,000,007 (1e9+7)即可。

Input
输入共一行,在一行中给出一个整数n (1<=n<=1,000,000,000)。


Output
对于每一个n,在一行中输出FB(n)%1,000,000,007 (1e9+7)。


Input示例
5


Output示例
2


思路:

1、首先我们考虑斐波那契函数:f(n)=f(n-1)+f(n-2)如果我们给括号内元素增大10倍会怎样呢?

F(10n)=F(10n-10)+F(10n-20);如果我们此时设定f【10】=1;f【20】=2;一样可以得到斐波那契数列,只不过,如果需要查询f【3】的时候,是要找f【30】内的元素。

那么同理,这个题也可以进行如此操作,主要是为了搞定括号内带有小数这个问题。

那么就有:



2、那么考虑到N比较大,那么肯定是要矩阵快速幂来解决这个问题的,那么我们接下来构造矩阵:



???中填入的就是矩阵构造出来的结果:



其能够满足递推式、

3、那么结果是多少呢?

我们不妨设定为:



我们显然知道F(0~40)=1;

那么ans=得到的矩阵的n-4次幂的第一行的和。

Ac代码:

#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define ll __int64
#define mod 1000000007
typedef struct Matrix
{
ll mat[36][36];
}matrix;
Matrix A,B;
Matrix matrix_mul(matrix a,matrix b)
{
matrix c;
memset(c.mat,0,sizeof(c.mat));
int i,j,k;
for(int i=0;i<34;i++)
{
for(int j=0;j<34;j++)
{
for(int k=0;k<34;k++)
{
c.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
c.mat[i][j]%=mod;
}
}
}
return c;
}
Matrix matrix_quick_power(matrix a,ll k)//矩阵快速幂0.0
{
matrix b;
memset(b.mat,0,sizeof(b.mat));
for(int i=0;i<34;i++)
b.mat[i][i]=1;//单位矩阵b
while(k)
{
if(k%2==1)
{
b=matrix_mul(a,b);
k-=1;
}
else
{
a=matrix_mul(a,a);
k/=2;
}
}
return b;
}
int main()
{
ll n;
while(~scanf("%I64d",&n))
{
if(n<=4)
{
printf("1\n");
continue;
}
int tmp1=0;
int tmp2=24;
memset(A.mat,0,sizeof(A.mat));
for(int i=0;i<10;i++)
{
for(int j=0;j<34;j++)
{
if(j==tmp1||j==tmp2)A.mat[i][j]=1;
else A.mat[i][j]=0;
}
tmp1++;
tmp2++;
}
for(int i=10;i<34;i++)
{
A.mat[i][i-10]=1;
}
ll output=0;
B=matrix_quick_power(A,n-4);
for(int i=0;i<34;i++)
{
output=(output+B.mat[0][i])%mod;
}
printf("%I64d\n",output);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  51nod 1358