来提供两个正确的做法:

  • 斐波那契数列双倍项的做法(附加证明)
  • 矩阵快速幂

一、双倍项做法

在偶然之中,在百度中翻到了有关于斐波那契数列的词条(传送门),那么我们可以发现一个这个规律$ \frac{F_{2n}}{F_{n}}=F_{n-1}+F_{n+1} $,那么我就想到了是不是可以用这个公式实现类似于快速幂之类的东西:power(n,m)=power(n*n,m/2) m mod 2=0 power(n,m)=power(n*n,m/2)*n m mod 2=1

快速幂这个东西,是分成偶数情况和奇数情况,所以我们只是知道偶数想的计算公式,所以我们接下来要推导一下奇数项的递归式

\[F_{2n}=F_{n}\times(F_{n-1}+F_{n+1})
\]
\[F_{2n+2}=F_{n+1}\times(F_{n}+F_{n+2})
\]

那么我们就是要从\(F_{2n}\)和\(F_{2n+2}\)推导求出\(F_{2n+1}\)

\[F_{2n+1}=F_{2n+2}-F_{2n}
\]
\[F_{2n+1}=F_{n+1}\times(F_{n}+F_{n+2})-F_{n}*(F_{n-1}+F_{n+1})
\]
\[F_{2n+1}=F_{n+1}\times F_{n}+F_{n+1}\times F_{n+2} - F_{n}\times F_{n-1}-F_{n}\times F_{n+1}
\]
\[F_{2n+1}=F_{n+1}\times F_{n+2}-F_{n}\times F_{n-1}
\]
\[F_{2n+1}=F_{n+1}\times(F_{n+1}+F_{n})-F_{n}\times(F_{n+1}-F_{n})
\]
\[F_{2n+1}={F_{n+1}}^2+{F_{n}}^2
\]

以上就是我们对于这个公式的推导

那么我们就得到了

**F[2n] = F[n+1]² - F[n-1]² = (2F[n-1] + F[n]) · F[n] **

F[2n+1] = F[n+1]² + F[n]²

那么,我们在写一个map,那么就可以不用全部都递归到底了,优化一下。

用map映射一下大数,映射到我们的答案上。

#include <bits/stdc++.h>
using namespace std;
const int Mod=1e9+7;//mod数
long long n;
map<long long,long long> ma;//搞映射
inline long long work(long long x){
if(x==1||x==0)return 1;//边界
if(ma.count(x))return ma[x];//count如果是返回1那么就是这个答案已经在map中映射过了,0就是没有
long long res=0,t=x/2;
if(x&1) res=work(t)*(work(t-1)+work(t+1))%Mod;//公式2
else res=work(t)*work(t)%Mod+work(t-1)*work(t-1)%Mod;//公式1
return ma[x]=res;
}
int main() {//主程序
cin>>n;
long long res=work(n-1)%Mod;
cout<<res<<endl;
return 0;
}

注:这个程序的复杂度是也差不多是log(n),也是非常优的解法


二、矩阵乘法解法

这个解法应该是这一道题的正解。

我是一个蒟蒻,还是只是初懂矩阵乘法的小白。

我就贴一下自己的代码,详细的题解还是看一下别的大佬的题解。

#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007 //Mod数
struct Matrix{//这个是矩阵的结构体
long long ma[2][2];
};
Matrix mul(Matrix A,Matrix B)//矩阵乘法
{
Matrix C;//答案矩阵
C.ma[0][0]=C.ma[0][1]=C.ma[1][0]=C.ma[1][1]=0;//初始化
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
for(int k=0;k<2;k++)
{
C.ma[i][j]=(C.ma[i][j]+A.ma[i][k]*B.ma[k][j])%mod;
}
}
}
return C;
}
Matrix pow_mod(Matrix A,long long n)//卡苏米+矩阵乘法优化
{
Matrix B;
B.ma[0][0]=B.ma[1][1]=1;
B.ma[0][1]=B.ma[1][0]=0;
while(n) {
if(n&1) B=mul(B,A);
A=mul(A,A);
n>>=1;
}
return B;
}
int main()
{
long long n;
Matrix A;
A.ma[0][0]=1;A.ma[0][1]=1;
A.ma[1][0]=1;A.ma[1][1]=0;//初始的数组
Matrix ans=pow_mod(A,n);
printf("%lld\n",ans.ma[0][1]);//输出答案
return 0;
}

注:关于矩阵乘法加速,这个矩阵有多种写法,这个只是其中的一种,不需要纠结于矩阵是否唯一。

【洛谷P1962 斐波那契数列】矩阵快速幂+数学推导的更多相关文章

  1. 洛谷P1962 斐波那契数列(矩阵快速幂)

    题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数) 题目描述 请 ...

  2. 洛谷- P1306 斐波那契公约数 - 矩阵快速幂 斐波那契性质

    P1306 斐波那契公约数:https://www.luogu.org/problemnew/show/P1306 这道题目就是求第n项和第m项的斐波那契数字,然后让这两个数求GCD,输出答案的后8位 ...

  3. 洛谷P1962 斐波那契数列【矩阵运算】

    洛谷P1962 斐波那契数列[矩阵运算] 题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) ( ...

  4. 洛谷P1962 斐波那契数列 || P1349 广义斐波那契数列[矩阵乘法]

    P1962 斐波那契数列 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数 ...

  5. 洛谷——P1962 斐波那契数列

    P1962 斐波那契数列 题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 ...

  6. 洛谷—— P1962 斐波那契数列

    https://www.luogu.org/problem/show?pid=1962 题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f ...

  7. 洛谷P1962 斐波那契数列题解

    题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数) 题目描述 请 ...

  8. HDU4549 M斐波那契数列 矩阵快速幂+欧拉函数+欧拉定理

    M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Sub ...

  9. 51nod1242 斐波那契数列 矩阵快速幂

    1242 斐波那契数列的第N项 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 #include<stdio.h> #define mod 100000000 ...

随机推荐

  1. C#开发之基于NPOI的操作Excel开发体验

    最近遇到一个数据导入的需求,语言是.net framework 4.7的C#.但是,这次主要探讨NPOI的体验,原则就是向前兼容.所以采用.xls的支持.网上的资料,我稍微整合了一些. #1 单元格下 ...

  2. 每天凌晨 2:00 将 mysql 数据库 testdb ,备份到文件中。

    步骤:1, 首先编写一个 脚本 backupdb.sh#!/bin/bash #备份路径 BACKUP=/data/backup/sql/dy #当前时间 DATETIME=$(date +%Y-%m ...

  3. java并发编程JUC第十二篇:AtomicInteger原子整型

    AtomicInteger 类底层存储一个int值,并提供方法对该int值进行原子操作.AtomicInteger 作为java.util.concurrent.atomic包的一部分,从Java 1 ...

  4. 4.2tensorflow多层感知器MLP识别手写数字最易懂实例代码

    自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取: https://www.cnblogs.com/bclshuai/p/11380657.html 1.1  多层感知器MLP(m ...

  5. 6.17考试总结(NOIP模拟8)[星际旅行·砍树·超级树·求和]

    6.17考试总结(NOIP模拟8) 背景 考得不咋样,有一个非常遗憾的地方:最后一题少取膜了,\(100pts->40pts\),改了这么多年的错还是头一回看见以下的情景... T1星际旅行 前 ...

  6. Hive和Spark分区策略

    1.概述 离线数据处理生态系统包含许多关键任务,最大限度的提高数据管道基础设施的稳定性和效率是至关重要的.这边博客将分享Hive和Spark分区的各种策略,以最大限度的提高数据工程生态系统的稳定性和效 ...

  7. 图解 Redis | 不多说了,这就是 RDB 快照

    大家好,我是小林. 虽说 Redis 是内存数据库. 但是它为数据的持久化提供了两个技术,分别是「 AOF 日志和 RDB 快照」. 这两种技术都会用各用一个日志文件来记录信息,但是记录的内容是不同的 ...

  8. WEB安全新玩法 [5] 防范水平越权之查看他人订单信息

    水平越权是指系统中的用户在未经授权的情况下,查看到另一个同级别用户所拥有的资源.水平越权会导致信息泄露,其产生原因是软件业务设计或编码上的缺陷.iFlow 业务安全加固平台可以缓解部分场景下的水平越权 ...

  9. 关于React Native常用技巧

    Doctor命令检查所需环境 @2019年11月18日,React Native v新增了一个环境检查和诊断命令行,可以帮助新手修复环境,输出环境依赖报告. 先建好的一个React Native项目, ...

  10. 界面设计ie8 笔记

    1.ie8 jsp中设置 margin:0 auto 无效 解决方法  在html 标签改为<!DOCTYPE html> 2.ie8 input file 无法通过js触发点击事件,网上 ...