P1962 斐波那契数列-题解(矩阵乘法扩展)
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 斐波那契数列-题解(矩阵乘法扩展)的更多相关文章
- Luogu P1962 斐波那契数列(矩阵乘法模板)
传送门(其实就是求斐波那契数列....) 累了 明天再解释 做这道题需要一些关于矩阵乘法的基础知识. 1. 矩阵乘法的基础运算 只有当矩阵A的列数等于矩阵B的行数时,A与B可以相乘(A的行数不一定等于 ...
- 题解——洛谷P1962 斐波那契数列(矩阵乘法)
矩阵乘法加速线性递推的典型 大概套路就是先构造一个矩阵\( F \)使得另一初始矩阵\( A \)乘以\( F^{x} \)能够得出第n项 跑的飞快 虽然我也不知道那个矩阵要怎么构造 或许就像我使用了 ...
- P1962 斐波那契数列 【矩阵快速幂】
一.题目 P1962 斐波那契数列 二.分析 比较基础的递推式转换为矩阵递推,这里因为$n$会超出$int$类型,所以需要用矩阵快速幂加快递推. 三.AC代码 1 #include <bits/ ...
- 【洛谷P1962 斐波那契数列】矩阵快速幂+数学推导
来提供两个正确的做法: 斐波那契数列双倍项的做法(附加证明) 矩阵快速幂 一.双倍项做法 在偶然之中,在百度中翻到了有关于斐波那契数列的词条(传送门),那么我们可以发现一个这个规律$ \frac{F_ ...
- 洛谷P1962 斐波那契数列题解
题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数) 题目描述 请 ...
- 洛谷P1962 斐波那契数列 (矩阵快速幂)
学了矩阵,练一下手... 1 #include<bits/stdc++.h> 2 typedef long long ll; 3 const ll mod=1e9+7; 4 using n ...
- 洛谷P1962 斐波那契数列 || P1349 广义斐波那契数列[矩阵乘法]
P1962 斐波那契数列 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数 ...
- 洛谷P1962 斐波那契数列【矩阵运算】
洛谷P1962 斐波那契数列[矩阵运算] 题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) ( ...
- 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)} ...
随机推荐
- Java学习点滴——对象实例化
基于<Java编程思想>第四版 构造与析构 在C++中通过构造函数和析构函数来保证:对象在使用前被正确初始化,在使用后被正确回收.Java中同样存在构造函数,但是没有析构函数.之所以没有析 ...
- Odoo薪酬管理 公式配置
薪酬计算的一般原理是:在基本工资的基础上,加上各种津贴,减去社保.公积金.个税等各种扣除项之后,得出最终的实发工资.此外,还要计算社保.公积金等公司应该承担的部分. 在同一公司中,针对不同的地区.不同 ...
- OPPO K3在哪里打开USB调试模式的完美方法
当我们使用pc链接安卓手机的时候,如果手机没有开启USB调试模式,pc则无法成功识别我们的手机,这个时候我们需要找解决方法将手机的USB调试模式打开,今天我们介绍OPPO K3如何开启USB调试模式的 ...
- <自动化测试方案_9>第九章、持续集成平台搭建
第九章.持续集成平台搭建 (一)什么是持续集成 参考文章地址:https://blog.csdn.net/qq_32261399/article/details/76651376 敏捷软件开发(英语: ...
- ext前后台数据传输的标准化
一.标准化的数据传输是什么 这里所说的标准化主要是指,使用代理提交数据时,格式必须统一化.标准化,而服务器返回的数据格式也必须是标准化的数据. 简言之,使用代理提交数据时,前台--->后台,后台 ...
- 20年硅谷技术牛人到访DataPipeline谈:技术如何与业务平衡发展
导读:技术人员的常态是“左手支持业务签单,右手提升系统性能”,却经常陷入技术和业务该如何平衡发展的困惑?今天,且听一位硅谷牛人分享他的平衡之道. 以个人名誉申请31个国内外技术和产品专利,中国最佳CT ...
- C语言面试程序阅读整理
一.数组和指针 1.数组和指针的存储 写出下面的输出结果: char str1[] = "abc"; char str2[] = "abc"; const ch ...
- redis数据库的基础
redis数据库 redis有以下三个特点 redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用 redis不仅仅支持简单的key-value类型的数据,同时还提 ...
- XMind 8 Pro 破解
1.补丁下载地址 链接:https://pan.baidu.com/s/146qcwkvOGCAneIXabSZSUA 提取码:wygs 2.安装 XMind 8 Pro, 运行 3. 去除检查 ...
- VUE的一个数据绑定与页面刷新相关的bug
1.场景: N层嵌套的循环查询业务场景,框架是vue.其中在最后一层查完之后,还需要查其中每一项的两个属性,类型都是列表.查完之后将其赋值给一个变量用于页面展示.代码如下: (1)异常代码: getS ...