https://www.luogu.org/problemnew/show/P1962(题目传送)

n的范围很大,显然用普通O(N)的递推求F(n)铁定超时了。这里介绍一种用矩阵快速幂实现的解法:

首先普及一下矩阵乘法:

一个m*q的m行q列的矩阵A*一个q*n的q行n列的矩阵B得到一个m*n的m行n列的矩阵AB,则有:

通俗的讲,就是新矩阵第i行j列的数等于第一个矩阵第i行的q个数分别乘第二个矩阵的第j列的q个数并把它们加起来的和。注意,矩阵乘法满足结合律和分配律,但不满足交换律。

我们可以把第n项F(n)、第n-1项F(n-1)写成一个1*2的矩阵[Fn  ​​Fn-1] 并考虑怎样由前面的[Fn-1  ​​Fn-2]推过来。可以先把[Fn  ​​Fn-1]写成[1*Fn-1+1*Fn-2  ​​1*Fn-1+0*Fn-2]的形式,试推导一个矩阵base,使

[Fn-1  ​​Fn-2]*base=[Fn  ​​Fn-1]=[Fn-1+Fn-2  ​​Fn-1],因为Fn-1和Fn-2都在结果矩阵的第一列以系数为1的形式出现,结果矩阵是一个1*2的矩阵,所以base为一个2*2的矩阵,且第一列为1,1;

Fn-1和Fn-2在结果矩阵的第二列以系数为1、0的形式出现,所以结果矩阵第二列为1,0。即base= ,[Fn-1  ​​Fn-2]*=[Fn  ​​Fn-1]。

同理可以推出[Fn-2  ​​Fn-3]**=[Fn  ​​Fn-1]…………[F2 F1]*^(n-2)=[Fn Fn-1]。

此时本题的核心便是计算出base=的n-2次方就行了,可以用矩阵快速幂做(换汤不换药)

代码如下:

 #include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const long long mod=;
struct matrix{ //用结构体构建矩阵类型
long long a[][];
}ans,a;
int init() //初始化矩阵。ans存放题解中提到的1*2的矩阵,这里为了统一用同一种矩
//阵乘法的处理,又发现若矩阵的一行(或一列)全为0,则乘法的结果矩阵
//的对应行(或列)也全为0,不影响结果,便用0把ans扩充成2*2的矩阵了 。
{
ans.a[][]=ans.a[][]=;
a.a[][]=a.a[][]=a.a[][]=;
}
matrix operator *(matrix a,matrix b)//矩阵乘法实现(运算符重载)
{
matrix c;
for(int i=;i<=;i++)
for(int j=;j<=;j++) c.a[i][j]=;
for(int i=;i<=;i++)
for(int j=;j<=;j++)
for(int k=;k<=;k++)
c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%mod;
return c;
}
int main()
{
long long n;
cin>>n;
if(n<=)
{
cout<<;
return ;
}
long long b=n-;
init();
while(b) //万年不变的快速幂
{
if(b&) ans=ans*a;
a=a*a;
b>>=;
}
cout<<ans.a[][];
return ;
}

P1962 斐波那契数列-题解(矩阵乘法扩展)的更多相关文章

  1. Luogu P1962 斐波那契数列(矩阵乘法模板)

    传送门(其实就是求斐波那契数列....) 累了 明天再解释 做这道题需要一些关于矩阵乘法的基础知识. 1. 矩阵乘法的基础运算 只有当矩阵A的列数等于矩阵B的行数时,A与B可以相乘(A的行数不一定等于 ...

  2. 题解——洛谷P1962 斐波那契数列(矩阵乘法)

    矩阵乘法加速线性递推的典型 大概套路就是先构造一个矩阵\( F \)使得另一初始矩阵\( A \)乘以\( F^{x} \)能够得出第n项 跑的飞快 虽然我也不知道那个矩阵要怎么构造 或许就像我使用了 ...

  3. P1962 斐波那契数列 【矩阵快速幂】

    一.题目 P1962 斐波那契数列 二.分析 比较基础的递推式转换为矩阵递推,这里因为$n$会超出$int$类型,所以需要用矩阵快速幂加快递推. 三.AC代码 1 #include <bits/ ...

  4. 【洛谷P1962 斐波那契数列】矩阵快速幂+数学推导

    来提供两个正确的做法: 斐波那契数列双倍项的做法(附加证明) 矩阵快速幂 一.双倍项做法 在偶然之中,在百度中翻到了有关于斐波那契数列的词条(传送门),那么我们可以发现一个这个规律$ \frac{F_ ...

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

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

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

    学了矩阵,练一下手... 1 #include<bits/stdc++.h> 2 typedef long long ll; 3 const ll mod=1e9+7; 4 using n ...

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

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

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

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

  9. HDU 4549 M斐波那契数列(矩阵快速幂)

    题目链接:M斐波那契数列 题意:$F[0]=a,F[1]=b,F[n]=F[n-1]*F[n-2]$.给定$a,b,n$,求$F[n]$. 题解:暴力打表后发现$ F[n]=a^{fib(n-1)} ...

随机推荐

  1. Django之CSRF跨站请求伪造(老掉牙的钓鱼网站模拟)

    首先这是一个测试的代码 请先在setting页面进行下面操作 注释完成后,开始模拟钓鱼网站的跨站请求伪造操作: 前端代码: <!DOCTYPE html> <html lang=&q ...

  2. Windows环境下使用pip install安装lxml库

    lxml是Python语言和XML以及HTML工作的功能最丰富和最容易使用的库.lxml是为libxml2和libxslt库的一个Python化的绑定.它与众不同的地方是它兼顾了这些库的速度和功能完整 ...

  3. rocketmq延时消息

    rocketmq提供一种延时消息的解决方案,就是在特定的时间到了,消息才会被投递出去供consumer消费. 总体来是简单的场景是满足了,但是需要注意的是延时的时间是需要按照默认配置的延时级别去配置的 ...

  4. 理解SignalR

    ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现即时通信(即:客户端(Web页面)和服务器端可以互相实时的通知消息及调用方法),即时通讯W ...

  5. iBatis第五章:事务管理

    ---------------------------- 1.什么是事务 ------------------------------ 什么是事务? 需要注意的是,事务的概念不是针对某个特定的数据库的 ...

  6. 不停服务,动态加载properties资源文件

    系统运行过程中,我们用注解@Value("${****}")可以获取资源文件中的内 容,获取的内容会被存储在spring缓存中,因此如果我们修改了资源文件,要 想读取到修改后的内容 ...

  7. 前端/C# 前后台交互文件上传、下载

    试了很多方式,最终确认这个全面简单版的.废话不多说,贴码. 文件上传 input的type命名为file,即可实现文件上传.嗯~~~现在html还是很强大的.Good! 前端 单个文件上传 Html: ...

  8. C++11のlambd表达式

    在其他语言中,我们常见lambda表达式,c++11中也引入了. 利用Lambda表达式,可以方便的定义和创建匿名函数.今天,我们就来简单介绍一下C++中Lambda表达式的简单使用. 一.lambd ...

  9. Linux云计算运维-MySQL

    0.建初心 优秀DBA的素质 1.人品,不做某些事情2.严谨,运行命令前深思熟虑,三思而后行,即使是依据select3.细心,严格按照步骤一步一步执行,减少出错4.心态,遇到灾难,首先要稳住,不慌张, ...

  10. Apache Jakarta Commons 工具集简介

    Apache Jakarta Commons 工具集简介[转] Apache Commons包含了很多开源的工具,用于解决平时编程经常会遇到的问题,减少重复劳动.我选了一些比较常用的项目做简单介绍.文 ...