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. Android常用的四种布局(或者说是五种)

    一.FrameLayout(帧布局): 显示特点:所有的子控件默认显示在FrameLayout的左上角,会重叠在一起显示. 常用属性: layout_gravity(设置给子控件,调整控件在容器内的重 ...

  2. 在react中实现打印功能

    最近项目中,前端采用react+antd+dva的组合,已经完成了后头管理类系统产品的更新迭代工作. 今天有一个新需求,需要在后台管理系统中实现点击打印完成指定页面的打印功能. 之前也没接触过,只知道 ...

  3. linux 子系统折腾记 (三)

    所以说,英文真是个好东西,很多资料都只有英文版本,要是不懂英文,甚至你不知道这个资料的存在,更别提用蹩脚的翻译软件去翻译了. wsl 的资料:https://docs.microsoft.com/zh ...

  4. python高级(4)—— 虚拟环境安装使用

    虚拟环境 什么是虚拟环境 对电脑稍微有点常识的朋友相信都玩过,比如VMware,virtualbox,或者你用电脑端的模拟器玩手机端的游戏也是一样,其实就是一个假的空间,在Python这里,虚拟环境就 ...

  5. winserver-记录共享文件夹操作日志

    abstract 1.在共享文件夹上开启审计. 2.在日志中查看操作记录. 开启审计 共享文件夹属性 选择审计 添加审计用户 选择用户及审计事件 日志查看 运行eventvwr 在windowslog ...

  6. L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到了一个处理错误(转)

    L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到了一个处理错误   错误描述:“ L2TP连接尝试失败,因为安全层在初始化与远程计算机的协商时遇到了一个处理错误” 只有这个没有错误码. ...

  7. nginx 配置 rewrite 跳转

    在访问 test.com 网站时,会自动跳转到 www.test.com ,这是因为该网站做了 URL rewrite 重定向,一般网页重定向跳转分为两种,301 和 302 :301,302 都是H ...

  8. 【js】字符串方法

    let str = 'na'; console.log(str.repeat('3'));//nanana console.log(str.startsWith('n'));//true consol ...

  9. Linux内存管理专题

    Linux的内存管理涉及到的内容非常庞杂,而且与内核的方方面面耦合在一起,想要理解透彻非常困难. 在开始学习之前进行了一些准备工作<如何展开Linux Memory Management学习?& ...

  10. opendir函数和readdir函数内涵及用法

    工作中遇到奇怪的事,加载增量的时候加载不上.于是开始分析原因,log里边没有任何错误信息,只有加载完成的标志.增量的数据在目录里边是存在的,但是显示的目录大小却不是4096,而是17,不知道为什么.后 ...