浅谈斐波那契数列和卡特兰数
斐波那契数列
斐波那契数列是我们较为熟悉的一类数列了,在学习递归和递推的时候我们就已经能求解
卢卡斯数列#
卢卡斯数列经常作为一个工具来研究斐波那契数列,所以这里也会提到一部分
其定义如下:
斐波那契数列通项公式#
第
例如我们有下面的公式
证明:
由上面我们知道斐波那契数列的递推公式为
我们设
为什么这么设呢,这是因为我们发现构造一个等差数列的话是很难的,所以我们尝试构造一个等比数列
拆开移项得到
解得
将其带回原式子可以得到
然后根据等比数列通项公式,我们得到
然后上式乘以
或者可以看看上面这位b站大佬的证明过程,比上面的方法更好理解。
需要注意的是,这个公式对于精度要求较高。
卢卡斯数列的通项公式#
其实他的通项公式和斐波那契的很像
事实上有:
其实还有一个式子:
矩阵加速求斐波那契数列#
我们在之前的题目遇见的求斐波那契数列第
设
试着来推导一个矩阵
因为
综上所述,
定义初始矩阵
注意矩阵乘法不满足交换律,所以不能将两个矩阵反过来,另外,对于
参考代码:
#include<bits/stdc++.h>
#define int long long
#define P 1000000007
#define N 110
using namespace std;
int n;
struct sb{int m[N][N];}ans,base;
inline sb cheng(sb a,sb b,int ok)
{
sb c;
for(int i=1;i<=ok;i++)
{
for(int j=1;j<=ok;j++)
{
c.m[i][j]=0;
for(int k=1;k<=ok;k++)
c.m[i][j]=(c.m[i][j]+a.m[i][k]*b.m[k][j])%P;
}
}
return c;
}
inline sb jzksm(sb x,int y)
{
sb res=x;y--;
while(y)
{
if(y&1)res=cheng(res,x,2);
x=cheng(x,x,2);
y>>=1;
}
return res;
}
signed main()
{
cin>>n;
if(n==1||n==2){puts("1");return 0;}
ans.m[1][1]=1;ans.m[1][2]=1;
base.m[1][1]=1;base.m[1][2]=1;
base.m[2][1]=1;base.m[2][2]=0;
base=jzksm(base,n-2);
ans.m[1][1]=(base.m[1][1]+base.m[1][2])%P;
cout<<ans.m[1][1]<<endl;
return 0;
}
快速倍增法#
我们可以用上面的方法得到下面两个等式:
于是我们可以通过这样的方法快速计算两个相邻的斐波那契数(常数比矩阵法小)。返回值是一个二元组
性质#
这里只列出一部分。
-
卡西尼性质:
-
附加性质:
-
性质二中
,我们得到 -
由性质三可以归纳证明,
-
上述性质可逆,即
-
GCD 性质:
斐波那契数列和卢卡斯数列#
不难发现有个上面提到的式子和三角函数公式很像:
上面两个式子很像。
这两个式子也很像。
那么我们大胆推测一下,是不是卢卡斯数列构成的图像很像余弦函数,斐波那契数列构成的图像很像正弦函数?
根据:
可以得到两下标之和的等式:
于是推论就有二倍下标的等式:
这也是一种快速倍增下标的办法。
模意义下周期性#
考虑模
卡特兰数
卡特兰数也算是比较常见的一种
其问题灵活多变,较为经典的有:
-
在圆上选
个点,将这些点成对连接起来使得所得到的 条线段不相交的方案数。 -
一个栈的进栈序列为
有多少个不同的可能的出栈序列。 -
个节点可以构造多少个不同的二叉树?
如果是给定两种操作,一个操作的个数不超过另一种操作的个数,或者两种操作没有交集,求合法操作方案的总数,那么一般就是卡特兰数。
其对应的序列为
递推式#
为了防止冲突,用
该递推关系的解为:
实际上最常用的是第一个公式的变形:
直接套用公式二即可。
参考代码:
#include<bits/stdc++.h>
#define int long long
#define N 1000100
using namespace std;
int n,c[N];
signed main()
{
c[0]=1;
cin>>n;
for(int i=1;i<=n;i++)
c[i]=(c[i-1]*(4*i-2))/(i+1);
cout<<c[n]<<endl;
return 0;
}
封闭形式#
卡特兰数的递推式我们前面说过了,也就是这个:
其中
我们发现卡特兰数的递推式与卷积的形式很相似,因此我们用卷积来构造关于
解得:
那么这就产生了一个问题:我们应该取哪一个根呢?我们将其分子有理化:
代入
因此我们得到了卡特兰数生成函数的封闭形式:
参考自OIWIKI
作者: 北烛青澜
出处:https://www.cnblogs.com/Multitree/p/17429558.html
本站使用「CC BY 4.0」创作共享协议,转载请在文章明显位置注明作者及出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!