洛谷——P1349 广义斐波那契数列
题目描述
广义的斐波那契数列是指形如an=p*an-1+q*an-2的数列。今给定数列的两系数p和q,以及数列的最前两项a1和a2,另给出两个整数n和m,试求数列的第n项an除以m的余数。
输入输出格式
输入格式:
输入包含一行6个整数。依次是p,q,a1,a2,n,m,其中在p,q,a1,a2整数范围内,n和m在长整数范围内。
输出格式:
输出包含一行一个整数,即an除以m的余数。
输入输出样例
1 1 1 1 10 7
6
说明
数列第10项是55,除以7的余数为6。
我们来通过这个题讲一下斐波那契数列怎么用矩阵乘法来优化吧
我们知道对于斐波那契数列我们有这样的递推式:f[n]=f[n-1]+f[n-2]
通常情况下,我们计算f(n)的时间复杂度就是O(n)(分别计算f(1), f(2) ... f(n - 1)).
但是当n很大又或者还有其他处理的复杂度一叠加便会超时。
所以当n很大的时候,我们的递推式便不起作用了,我们应该像一种办法来优化一下这个递推式,怎么办呢,我们看到这个式子有加,有乘,我们就一般会想到矩阵乘法(这时候就有人会问了,博主,你眼瞎啊,明明就是个加法的式子,你说他有乘法。。。)额、、对于这个问题,我们可以将上面的式子做一个小小的变形,将它变成f[n]=f[n-1]*1+f[n-2]*1, f[n-1]=f[n-1]*1+f[n-2]*0
我们在这个地方普及一下矩阵乘法优化递推式的特征:形如f(n) = a1 * f(n - 1) + a2 * f(n - 2) + ... + ak * f(n - k)+c (c为常数)
然后我们可以将他组成这样的一个矩阵

然后我们进行矩阵乘法
来,看看代码:
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define mod 100000000
using namespace std;
int n;
int read()
{
,f=; char ch=getchar();
;ch=getchar();}
+ch-',ch=getchar();
return x*f;
}
struct Node
{
][];
Node(){memset(m,,sizeof(m));}
}mb,ans;
int GCD(int a,int b)
{
) return a;
return GCD(b,a%b);
}
Node operator*(Node a,Node b)
{
Node c;
;i<=;i++)
;j<=;j++)
;k<=;k++)
c.m[i][j]=(c.m[i][j]%mod+a.m[i][k]*b.m[k][j]%mod)%mod;
return c;
}
int main()
{
n=read();n--;
mb.m[][]=mb.m[][]=mb.m[][]=;
ans.m[][]=ans.m[][]=;
while(n)
{
&n) ans=ans*mb;
mb=mb*mb;n>>=;
}
cout<<ans.m[][];
;
}
矩阵乘法优化斐波那契
对于这个式子,我们可以根据朴素的斐波那契的矩阵乘法的形式将式子推出来

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
long long q,p,a1,a2,n,mod;
long long read()
{
,f=; char ch=getchar();
;ch=getchar();}
+ch-',ch=getchar();
return x*f;
}
struct Node
{
][];
Node(){memset(m,,sizeof(m));}
}begin,ans;
Node operator*(Node a,Node b)
{
Node c;
;i<=;i++)
;j<=;j++)
;k<=;k++)
c.m[i][j]=(c.m[i][j]%mod+(a.m[i][k]%mod*b.m[k][j]%mod)%mod)%mod;
return c;
}
int main()
{
p=read(),q=read(),a1=read(),a2=read();
n=read(),mod=read();n-=;
ans.m[][]=a2,ans.m[][]=a1;
begin.m[][]=p,begin.m[][]=q,begin.m[][]=;
while(n)
{
) ans=ans*begin;
begin=begin*begin;
n>>=;
}
==) cout<<ans.m[][]%mod;
][]%mod;
;
}
洛谷——P1349 广义斐波那契数列的更多相关文章
- 洛谷P1349 广义斐波那契数列(矩阵快速幂)
P1349 广义斐波那契数列 https://www.luogu.org/problemnew/show/P1349 题目描述 广义的斐波那契数列是指形如an=p*an-1+q*an-2的数列.今给定 ...
- 洛谷——P1349 广义斐波那契数列(矩阵加速)
P1349 广义斐波那契数列 题目描述 广义的斐波那契数列是指形如$an=p\times a_{n-1}+q\times a_{n-2}$?的数列.今给定数列的两系数$p$和$q$,以及数列的最前两项 ...
- 洛谷P1349 广义斐波那契数列
传送门 话说谁能告诉我矩阵怎么用latex表示…… 差不多就这样 //minamoto #include<iostream> #include<cstdio> #include ...
- 洛谷P1962 斐波那契数列 || P1349 广义斐波那契数列[矩阵乘法]
P1962 斐波那契数列 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数 ...
- P1349 广义斐波那契数列(矩阵加速)
P1349 广义斐波那契数列 题目描述 广义的斐波那契数列是指形如an=pan-1+qan-2的数列.今给定数列的两系数p和q,以及数列的最前两项a1和a2,另给出两个整数n和m,试求数列的第n项an ...
- P1349 广义斐波那契数列(矩阵乘法)
题目 P1349 广义斐波那契数列 解析 把普通的矩阵乘法求斐波那契数列改一改,随便一推就出来了 \[\begin{bmatrix}f_2\\f_1 \end{bmatrix}\begin{bmatr ...
- P1349 广义斐波那契数列
题目描述 广义的斐波那契数列是指形如an=p*an-1+q*an-2的数列.今给定数列的两系数p和q,以及数列的最前两项a1和a2,另给出两个整数n和m,试求数列的第n项an除以m的余数. 输入输出格 ...
- Luogu P1349 广义斐波那契数列
解题思路 既然广义斐波那契,而且数据范围这么大,那么我们使用矩阵快速幂来进行求解.大家都知道斐波那契的初始矩阵如下 $$\begin{bmatrix}1&1\\1&0\end{bmat ...
- 【洛谷P1962】斐波那契数列
斐波那契数列 题目链接:https://www.luogu.org/problemnew/show/P1962 矩阵A 1,1 1,0 用A^k即可求出feb(k). 矩阵快速幂 #include&l ...
随机推荐
- bzoj 2375: 疯狂的涂色
2375: 疯狂的涂色 Time Limit: 5 Sec Memory Limit: 128 MB Description 小t非常喜爱画画,但是他还是一个初学者.他最近费尽千辛万苦才拜到已仙逝的 ...
- CF540 C BFS 水
'.'->'X' 前者走后变成后者,后者除了是终点不能再走.初始位置是X很傻的以为这样从初始点走出去后初始位置就变成不能走了,实际上是还能走一次的. 其他就是BFS,路上记得把路变成X就好了 太 ...
- ① 设计模式的艺术-07.适配器(Adapter)模式
什么是适配器模式? 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 模式中的角色 目标接口(Target):客户所期待的接口 ...
- Centos7系统环境下Solr之Java实战(一)搭建solr服务器
搭建步骤 1.分别上传tomcat.sorl到指定文件夹并解压 2.把solr部署到Tomcat下 通过命令 cp apache-tomcat-7.0.47 /usr/local/sorl/tomca ...
- js学习阶段总结
typeof操作符:返回字符串,可能是“undefined”,“boolean”,“ string”,“number”,“object”,“function”中的一种,所以不能判断数组. NaN(No ...
- koa源码阅读[3]-koa-send与它的衍生(static)
koa源码阅读的第四篇,涉及到向接口请求方提供文件数据. 第一篇:koa源码阅读-0第二篇:koa源码阅读-1-koa与koa-compose第三篇:koa源码阅读-2-koa-router 处理静态 ...
- Linux下搜索命令
linux下用于查找文件的5个命令,有需要的朋友可以参考下.包括find,whereis,locate,which与type. linux下用于查找文件的5个命令,有需要的朋友可以参考下.包括find ...
- Django 1.10文档中文版Part4
2.10 高级教程:如何编写可重用的apps 2.10.1 重用的概念 The Python Package Index (PyPI)有大量的现成可用的Python库.https://www.djan ...
- C/C++——C语言跳出多重循环方法
c语言的break语句只能跳出离它最近的一层循环,但是我们有时候需要跳出多层循环,以下有几种跳出多重循环的方法: 1. 使用goto ; i < MAX1; i++) { ; j < MA ...
- 1.第一个hello word
1.生产者 #!/usr/bin/env python import pika connection = pika.BlockingConnection(pika.ConnectionParamete ...