一个简洁的斐波那契求法和它的简单应用

7 篇文章 0 订阅

这个简洁的求法其实是在做题的过程中发现的,但这道题的正规做法应该不是这样,所以我就先解释一下这种考找规律的斐波那契数列求法
事实上,只要细心观察,通过简单的数学推导很容易可以得到一个式子形如F(2n)=F(N)²+F(N+1)²就是F[N]=F[N/2]²+F[(N+1)/2]²
知道了这个式子后我们很容易的可以求出当目标为奇数时的递推关系(因为奇数本身除2自动约掉+1后除2即为n/2+1)但偶数会导致(N+1)/2自动约掉
n的大小一次可以减半,如果解决了偶数形式的问题我们就可以吧这一复杂度本来为2的n次方的递归问题优化为log2n性
于是我试着列了一个方程组如下图在这里插入图片描述
在得出
在这里插入图片描述
可以解决这个问题

所以我们可以用log2n的递归完成对斐波那契的求解
下面我们看一下这个题的原题和题解

题目描述

Keven特别喜欢斐波那契数列,已知 fib1=1fib2​=1,对于 n>=3n>=3n>=3。fibn​=fibn−2​+fibn−1​,并且他想知道斐波那契前 n 项平方和是多少? 为了防止答案过大,请将最后的答案模 1e9+7
输入描述:
第一行一个整数 n(1<=n<=1e18)
输出描述:
在一行中输出斐波那契数列的前 n 项平方和模 1e9+7

问题就是求前n项斐波那契的平方和,可是这个题目的输入数据非常之大我们很难暴力枚举解决问题
这是我们借助一个图来作为辅助

我们可以发现所有项的平方和共同组成了大矩形的面积也就是F[N]*F[N+1]我们只要求出这两项的值即可。而这时我们发现如果按照传统递归来求,时间也不够用,所以我们就用上文提到的规律来解决问题(在这里提一下,本题的正确解法应该是求矩阵快速幂)问题分解后代码就变得非常简短了(map是因为数组会越界)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll p = 1e9 + 7;
map<ll, ll>a;
ll n;
ll f(ll n)
{
    if (a[n] != 0)
        return a[n];
    ll t = n;
    n /= 2;
    if (t % 2)
      return a[t] = f(n) * f(n) % p + f(n + 1) * f(n + 1) % p;
    else
        return a[t] = (2 * f(n - 1) % p + f(n) % p) * f(n) % p;
}
int main()
{
    cin >> n;
    a[1] = a[2] = 1;
    cout << f(n) % p * f(n + 1) % p << endl;
    return 0}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值