两类递推数列

article/2025/9/14 3:38:04

此博客是抄论文的,你可以认为是转载的

1.线性递推数列

有限数列显然是线性递推数列。
无限数列 a i a_i ai设其生成函数为 A ( x ) A(x) A(x)
那么如果 A ( x ) A(x) A(x)能被表示为 C ( x ) B ( x ) \frac {C(x)}{B(x)} B(x)C(x)的形式,其中 B ( x ) [ x 0 ] = 1 B(x)[x^0] = 1 B(x)[x0]=1,则 A ( x ) A(x) A(x)是线性递推数列。
常数项为 1 1 1是因为递推式你要让 ∑ j = 0 b j a i − j = 0 \sum_{j=0}b_ja_{i-j} = 0 j=0bjaij=0来递推出 a i a_i ai所以常数项需要为 1 1 1
能这样表示是因为线性递推实质上就是 A ( x ) B ( x ) = C ( x ) A(x)B(x) = C(x) A(x)B(x)=C(x),其中 B ( x ) B(x) B(x)是我们的线性递推式。

对于一个线性递推数列 a i a_i ai,假设他前 i i i项的最短递推式是 R ( i ) R^{(i)} R(i),长度为 l i l_i li,那么如果 R ( i − 1 ) R^{(i-1)} R(i1)不是前 i i i项的最短递推式,那么有 l i ≥ max ⁡ ( l i − 1 , i + 1 − l i − 1 ) l_i \geq \max(l_{i-1},i+1-l_{i-1}) limax(li1,i+1li1),且这个等号是可以通过构造取到的。
首先 l i ≥ l i − 1 l_i \geq l_{i-1} lili1显然,如果 l i ≤ i − l i − 1 l_i \leq i-l_{i-1} liili1的话:
在这里插入图片描述
实在不知道怎么用语言表示交换和号。
也就是说如果 l i ≤ i − l i − 1 l_i \leq i-l_{i-1} liili1那么原来的递推式必可以继续用。

接下来我们给出在 R ( i − 1 ) R^{(i-1)} R(i1)不是前 i i i项的递推式时 l i = max ⁡ ( l i − 1 , i + 1 − l i − 1 ) l_i = \max(l_{i-1},i+1-l_{i-1}) li=max(li1,i+1li1)的构造方案,也就是 B M BM BM算法。
在这里插入图片描述
也就是说每次增长递推式,我们都可以用这个方法使得增长时 l i = max ⁡ ( l i − 1 , i + 1 − l i − 1 ) l_i = \max(l_{i-1},i+1-l_{i-1}) li=max(li1,i+1li1),不增长时 l i = l i − 1 l_i = l_{i-1} li=li1
因为上文证明了 l i ≥ max ⁡ ( l i − 1 , i + 1 − l i − 1 ) l_i \geq \max(l_{i-1},i+1-l_{i-1}) limax(li1,i+1li1),所以这个算法对于有限长度的数列求出的递推式一定是最短的。

对于无限长的数列,
在这里插入图片描述
所以我们只需要取最短递推式长度的两倍即可。
边界情况:第一次增长递推式的时候, a i a_i ai应该是第一个非 0 0 0元素,那么 l i = i l_i = i li=i 0 0 0即为前 i i i个数的最短递推式,也就是根本没有递推,同时也满足 l i ≥ i + 1 − l i − 1 , ( l i − 1 = 0 ) l_i \geq i+1-l_{i-1},(l_{i-1}=0) lii+1li1,(li1=0)
这里需要纠正一个错误观念,一个最短线性递推式的最后一项是可以为 0 0 0的,因为假如一个长度为 n n n的递推式 F ( x ) F(x) F(x)对于 a n = ∑ i = 1 n F ( x ) [ x i ] a n − i a_n = \sum_{i=1}^n F(x)[x^i]a_{n-i} an=i=1nF(x)[xi]ani不成立,我们需要在递推式的最后补一个 0 0 0,这样 a n a_n an就不在递推式成立的范围内。
也就是说一个线性递推数列被表示为 S ( x ) R ( x ) \frac {S(x)}{R(x)} R(x)S(x)的形式,则它的递推式的长度是 R ( x ) R(x) R(x)的次数和 S ( x ) S(x) S(x)的次数加一取 max ⁡ \max max

线性递推求第 n n n项:
在这里插入图片描述
代码:luogu【模板】Berlekamp-Massey算法
在这里插入图片描述
C o d e : \mathcal Code: Code:(真的很短。)

#include<bits/stdc++.h>
#define rep(i,j,k) for(int i=(j),LIM=(k);i<=LIM;i++)
#define per(i,j,k) for(int i=(j),LIM=(k);i>=LIM;i--)
#define maxn 10005
#define pb push_back
#define vi vector<int>
#define mod 998244353
using namespace std;int n,m,a[maxn];
int Pow(int b,int k){ int r=1;for(;k;k>>=1,b=1ll*b*b%mod) if(k&1) r=1ll*r*b%mod;return r; }
vi BM(int *a,int n){ // a[0 ~ n] is usedvi r(1,1),p,t;int lt;rep(i,0,n){int d=0;rep(j,0,r.size()-1) d = (d + r[j] * 1ll * a[i-j]) % mod;		if(!d) continue;t = r;r.resize(max(r.size() , i+2-(r.size()-(r.size()!=0))));rep(j,0,p.size()-1) r[j+i-lt] = (r[j+i-lt] - 1ll * d * p[j]) % mod;int iv = Pow(d , mod-2);p = t , lt = i;rep(i,0,p.size()-1) p[i] = 1ll * p[i] * iv % mod;}return r; // a \times r = const 
}
typedef vi poly;
poly Mul(const poly &A,const poly &B,const poly &P){poly r(A.size() + B.size() - 1);rep(i,0,A.size()-1) rep(j,0,B.size()-1) r[i+j] = (r[i+j] + 1ll * A[i] * B[j]) % mod;per(i,r.size()-1,P.size()-1) if(r[i]){// in this problem P[P.size()-1] = 1 , so there is no need to getinv.int t = r[i];rep(j,1,P.size())r[i-j+1] = (r[i-j+1] - 1ll * P[P.size()-j] * t) % mod;}r.resize(P.size()-1);return r;
}int main(){scanf("%d%d",&n,&m);rep(i,0,n-1) scanf("%d",&a[i]);vi P = BM(a,n-1);rep(i,1,P.size()-1) printf("%d%c",(mod-(P[i]+mod)%mod) % mod," \n"[i==P.size()-1]);reverse(P.begin(),P.end());poly r(1,1),t(2,0);t[1] = 1;for(;m;m>>=1,t=Mul(t,t,P)) if(m&1)r = Mul(r,t,P);int ans = 0;rep(i,0,r.size()-1) ans = (ans + 1ll * r[i] * a[i]) % mod;printf("%d\n",(ans+mod)%mod);
}

向量序列的最短递推式:
在这里插入图片描述

矩阵的零化多项式:使得矩阵 M M M
f ( M ) = ∑ i = 0 n a i M i = 0 f(M) = \sum_{i=0}^n a_iM^i = 0 f(M)=i=0naiMi=0
矩阵的最小多项式:
零化多项式中次数最低的多项式。
如何求矩阵的最小多项式:
直接求 I , M , M 2 . . . {I,M,M^2...} I,M,M2...的最短递推式即可,对于稀疏矩阵可以做到 O ( n ( n + e ) ) O(n(n+e)) O(n(n+e))
在这里插入图片描述
BM与矩阵的特征多项式:
特征多项式是矩阵的一个零化多项式,
B M BM BM求出的最小多项式也是矩阵的一个零化多项式
在这里插入图片描述
最小多项式是特征多项式的一个因式,因为如果不是则可以做带余除法得到余式为更小的零化多项式。
对于一个线性递推问题,我们可以通过零化多项式得到线性递推式,所以在解决线性递推时可以找最小多项式(用BM),也可以求特征多项式。
但是特征多项式的最经典的解法是根据定义 ∣ λ − I E ∣ = 0 |\lambda - IE| = 0 λIE=0来求行列式后拉格朗日插值求出多项式, O ( n 4 ) O(n^4) O(n4)相较于 B M O ( n 3 ) BMO(n^3) BMO(n3)感觉没有什么竞争力,尽管特征多项式有 O ( n 3 ) O(n^3) O(n3)的巧妙解法,但是这个解法无法计算出线性递推的前 n n n项(就是不能用递推式的部分),有了前 n n n项那为什么不用 B M BM BM呢?
综上在信息学奥赛的当前时代最小多项式完爆特征多项式,很多打着特征多项式的旗子的题目都可以用BM解决。

接下来我们看一个例题:
「2018 集训队互测 Day 1」完美的旅行
n n n个点的有向图,一次旅行是走 a ≥ 1 a\geq1 a1步,愉悦值为起点和终点的编号 a n d and and和。
多次旅行的愉悦值是每次旅行的 a n d and and和,对于所有的愉悦值 0 ≤ x < n 0\leq x\lt n 0x<n 1 ≤ a ≤ m 1\leq a \leq m 1am的总步数,求愉悦值为 x x x总步数为 a a a的多次旅行方案数。

先求 a n d and and为集合 S S S的超集的方案数 f S f_S fS,然后用 F M T FMT FMT一次就可以求出 a n d and and为集合 S S S的方案数。
a n d and and为集合 S S S的超集的一次旅行走了 a a a步,可以发现就是邻接矩阵 A A A a a a次方的一些位置的和。
大小为 n n n的矩阵一定有次数 ≤ n \leq n n的特征多项式,所以一次旅行的走了 a a a步的那些答案就是一个 n n n阶线性递推。
假设一次旅行的生成函数为 G ( x ) G(x) G(x),则多次旅行的生成函数为 F ( x ) = 1 1 − G ( x ) F(x) = \frac 1{1 - G(x)} F(x)=1G(x)1
因为 G ( x ) G(x) G(x) n n n阶递推,所以 G ( x ) = S ( x ) R ( x ) G(x) = \frac {S(x)}{R(x)} G(x)=R(x)S(x),其中 R ( x ) R(x) R(x)次数 ≤ n \leq n n, S ( x ) S(x) S(x)次数 ≤ n − 1 \leq n-1 n1
F ( x ) = R ( x ) R ( x ) − S ( x ) F(x) = \frac {R(x)}{R(x) - S(x)} F(x)=R(x)S(x)R(x),分子次数可以为 n n n,所以 F ( x ) F(x) F(x) n + 1 n+1 n+1阶线性递推。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.整式递推数列


http://chatgpt.dhexx.cn/article/dIroD5Hm.shtml

相关文章

整式递推数列

详见钟子谦IOI2019国家集训队论文。 对于无限数列 { a i } \{a_i\} {ai​}和有限多项式数列 { P i } \{P_i\} {Pi​}满足 P 0 P_0 P0​非 0 0 0多项式。 若对任意 p > ∣ { P } ∣ − 1 p>|\{P\}|-1 p>∣{P}∣−1有 ∑ i 0 ∣ { P } ∣ − 1 a p − i P i ( p ) \su…

算法设计与分析:枚举和递推的运用 ————双关系递推数列

头歌实验&#xff1a; 第一关&#xff1a;双关系递推数列 任务描述 本关任务&#xff1a;运用枚举和递推的基本思想&#xff0c;通过编程计算出双关系递推数列。设集合 M 定义如下&#xff1a; 1.初始 1∈M&#xff1b; 2.若x∈M&#xff0c;则有2x1∈M&#xff0c;5x−1∈…

递推数列的计算

利用递归函数 我们最熟悉的一个递推数列就是斐波那契数列。 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , . . . 1, 1, 2, 3, 5, 8, 13, 21, ... 1,1,2,3,5,8,13,21,...&#xff0c;斐波那契数列规定数列的第一个元素和第二个元素都为1&#xff0c;后面的元素是前两个元素之和&#xff…

极限求解--递推型数列

本文来自于公众号【考研数学直线笔记】 0 序言 递推型数列&#xff0c;一般可以表示为x(n1)f(x(n))&#xff0c;这一类题目的基本思想都是“先证明数列的极限存在&#xff0c;然后再求出极限值”&#xff0c;求极限值比较简单&#xff0c;设极限求等式就行了&#xff0c;难点在…

Autohotkey window 下宏键盘、宏命令开发入门

? ? ? ? 我的AHK下载地址:https://github.com/dragon8github/Pandora/raw/master/pandora.exe AutoHotKey 下载:https://autohotkey.com/download/ 国内自制的ahk网站:https://www.autoahk.com/ 推荐下载installer 官方网站:https://www.autohotkey.com/docs/AutoHot…

【开源项目分享】GitHub中文排行榜 - 帮助你发现高分优秀中文项目-Java

榜单设立目的 &#x1f1e8;&#x1f1f3; GitHub中文排行榜&#xff0c;帮助你发现高分优秀中文项目&#xff1b;各位开发者伙伴可以更高效地吸收国人的优秀经验、成果&#xff1b;中文项目只能满足阶段性的需求&#xff0c;想要有进一步提升&#xff0c;还请多花时间学习高分…

HTML+CSS+JS+Servlet+MSQL搭建个人博客

3.应用技术&#xff1a;HTMLCSSJSJSPServletMSQL 前端后台管理。 4.开发环境&#xff1a;eclipsejdk1.8tomcat8.5 mysql5.7前端Layui。 二、前端 1.博客首页 博主和用户可以访问到博客系统的首页&#xff0c;首页内容主要包括导航条&#xff0c;文章推荐和登录注册管理模块…

用 Dev-C++ 编写简单的走迷宫小游戏

用 Dev-C 编写简单的走迷宫小游戏 前言基础版优化版 前言 以下是显示效果 B站视频讲解&#xff1a;【小游戏】用 Dev-C 编写简单的控制台走迷宫小游戏 【小游戏】用 Dev-C 编写简单的控制台走迷宫小游戏 基础版 用 # 代表墙 用 空格 代表空地 用 O 代表玩家 地图存储&#…

简单的迷宫问题(DFS/BFS分别求解)

简单的迷宫问题 题目描述输入样例输出样例 dfs解题思路(深搜)路线规划DFS特点C源码(DFS) bfs解题思路(广搜)路线规划测试代码段BFS特点C源码&#xff08;BFS&#xff09; 题目描述 现在需要你来规划一条路线&#xff0c;从起点到终点的最短路线。 给你一个nm的地图&#xff08;…

基于JAVA的简单迷宫游戏

一、实验要求 1. 迷宫游戏是非常经典的游戏&#xff0c;在该题中要求随机生成一个迷宫&#xff0c;并求解迷宫。 2. 要求游戏支持玩家走迷宫&#xff0c;和系统走迷宫路径两种模式。玩家走迷宫&#xff0c;通过键盘方向键控制&#xff0c;并在行走路径上留下痕迹&#xff1b;系…

C++实现简单的走迷宫

c实现简单走迷宫 用n*n个小方格代表迷宫&#xff0c;每个方格上有一个字符0或1&#xff0c;0代表这个格子不能走&#xff0c;1代表这个格子可以走。只能一个格子一个走&#xff0c;而且只能从一个格子向它的上、下、左、右四个方向走&#xff0c;且不能重复。迷宫的入口和出口分…

迷宫问题(简单模拟)

目录导航 图解体会领悟&#xff1a;代码实现&#xff08;Java&#xff09;&#xff1a;C语言版C版 为了复习递归&#xff0c;而模拟学习的。所以迷宫不大&#xff0c;总体是8行7列。 图解 A为起点&#xff0c;B为终点。 如下图在A和B之间设置挡板被隔绝之后&#xff0c;结果如…

超级简单的迷宫代码 初学者程序

迷宫 走迷宫一种比较有趣&#xff0c;操作简单的小游戏。 #include<stdio.h> #include<getch.h> #include<stdlib.h> #include<time.h> int main(int argc,const char*argv[]) {//构造迷宫地图char maze[10][10]{{#,#,#,#,#,#,#,#,#,#},{#,,#,#,#,#…

最简单的迷宫求解

在计算机中&#xff0c;我们可以把迷宫当做一个二维数组。其中0表示通路&#xff0c;1表示墙。 我们以下图为例&#xff0c;对于只有一条通路的简单迷宫进行求解 该迷宫存储在“Map.txt”文档中。 对于该迷宫&#xff0c;我们首先将入口点压入栈中&#xff0c;然后通过对该点…

JAVA 中实现的简单的迷宫小游戏

多的不说&#xff0c;直接上代码&#xff0c;就是一个简单的迷宫小游戏。 import java.awt.Color; import java.awt.Graphics; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.Random; import java.util.Stack; import javax.swing.JFr…

Python实现迷宫游戏

项目&#xff1a;迷宫游戏 摘要1.引言1.1研究的背景及意义1.2研究的内容 2.系统结构2.1系统的结构2.2基本思路 3.实现代码3.1Maze类3.2Player类3.3Controller类3.4主函数 4.实验5.总结和展望参考文献 摘要 本次实验设计了一款迷宫小游戏&#xff0c;采用用Python开发技术实现。…

C语言实现简单迷宫

C语言实现迷宫程序 前言 大家小时候一定都玩过迷宫这个游戏&#xff0c;很吸引人吧&#xff0c;有那种走不出来就不罢休的执着&#xff0c;然后走出来了觉得自己很强&#xff0c;自己可以了&#xff0c;接着激动的开始下一个关卡&#xff0c;慢慢的沉溺在迷宫的世界里了。 然…

如何使用C语言实现简单迷宫(递归和非递归实现 含图例)

1.非递归实现 简单迷宫&#xff1a;只有一条通路的迷宫 思路&#xff1a;在找迷宫通路的时候&#xff0c;我们往往是在给定入口(入口合法且为通路)的情况下&#xff0c;沿着入口的某个方向走&#xff08;此方向是通路&#xff09;。现给定走迷宫的方向&#xff1a;上、左、右…

简单迷宫(递归)

代码思路 1.创建二位数组作为迷宫 2.数字1为墙壁&#xff0c;2为经过的位置&#xff0c;3为死路&#xff0c;0为未探寻的位置 3,定义一个起点和终点&#xff0c;运用递归的方法&#xff0c;按照自己设计的寻找方向的优先级运行&#xff0c;直到让终点值为2则返回true&#x…

简单迷宫问题

简单迷宫问题 一、问题描述二、数据组织三、算法说明附录&#xff1a;完整代码 #简单迷宫问题 一、问题描述 给定一个MN得迷宫&#xff0c;求一条从指定入口到出口得迷宫路径。假设一个迷宫如图1所示&#xff0c;&#xff08;这里MN8)&#xff0c;其中每个方块用空白表示通道…