整式递推数列

article/2025/9/14 3:35:03

详见钟子谦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 ) \sum_{i=0}^{|\{P\}|-1} a_{p-i}P_i(p) i=0{P}1apiPi(p)
则称 P P P a a a的整式递推式。
对于有限数列 { a i } \{a_i\} {ai}也有此定义。
但是整式递推数列只指可以用 P P P描述的无限数列 { a i } \{a_i\} {ai}
举例:卡特兰数。
C n = 4 n − 2 n + 1 C n − 1 C_n=\frac{4n-2}{n+1}C_{n-1} Cn=n+14n2Cn1

C n ( n + 1 ) − C n − 1 ( 4 n − 2 ) = 0 C_n(n+1)-C_{n-1}(4n-2)=0 Cn(n+1)Cn1(4n2)=0
所以 P 0 ( x ) = x + 1 P_0(x)=x+1 P0(x)=x+1 P 1 ( x ) = 2 − 4 x P_1(x)=2-4x P1(x)=24x的有限多项式数列 { P 0 , P 1 } \{P_0,P_1\} {P0,P1}即为卡特兰数的整式递推式。

整式递推式 { P i } \{ P_i \} {Pi}的阶数为 ∣ P ∣ − 1 |P|-1 P1,其次数为 max ⁡ i = 0 ∣ P ∣ − 1 deg ⁡ P i \max_{i=0}^{|P|-1}\deg{P_i} maxi=0P1degPi

微分有限:多项式 A ( x ) A(x) A(x)为微分有限的当且仅当存在有限多项式数列 { Q } \{Q\} {Q}
满足 Q ∣ Q ∣ − 1 ≠ 0 Q_{|Q|-1}\neq0 QQ1=0(注意我们的数列都是从 0 0 0开始编号的,所以这句话的意思是最后一项非 0 0 0),
∑ i = 0 ∣ Q ∣ − 1 Q i ( x ) A ( i ) ( x ) = 0 \sum_{i=0}^{|Q|-1}Q_i(x)A^{(i)}(x)=0 i=0Q1Qi(x)A(i)(x)=0(其中 A ( i ) ( x ) A^{(i)}(x) A(i)(x) A ( x ) A(x) A(x)关于 x x x i i i次导数)。

代数形式幂级数:先通过那模糊的论文一句话描述猜测:
A ( x ) A(x) A(x)为代数形式幂级数的意思是 A ( x ) A(x) A(x)是一个方程的根。
这个方程的解是多项式 A ( x ) A(x) A(x)
也就是形如 ∑ i = 0 K i ( x ) f ( x ) = 0 \sum_{i=0} K_{i}(x)f(x)=0 i=0Ki(x)f(x)=0,其中 K i ( x ) K_i(x) Ki(x)是有理分式(多项式除多项式)。
最后解出来是 f ( x ) = A ( x ) f(x)=A(x) f(x)=A(x)
如果存在这样一个方程那么 A ( x ) A(x) A(x)就是代数形式幂级数。
也就是 A ( x ) A(x) A(x)在有理分式域上是代数的(但是并不代表 A ( x ) A(x) A(x)是有理分式,但他也可以是)。

定理2.1:
无限数列 { a } \{a\} {a}的普通生成函数为 A ( x ) A(x) A(x),那么其为整式递推数列当且仅当 A ( x ) A(x) A(x)为微分有限的。
证明:
1.充分性:
如果有 ∑ i = 0 m Q i ( x ) A ( i ) ( x ) = 0 \sum_{i=0}^m Q_i(x)A^{(i)}(x)=0 i=0mQi(x)A(i)(x)=0
发现 A ( i ) ( x ) A^{(i)}(x) A(i)(x)其实和 A ( x ) x − i A(x)x^{-i} A(x)xi就是每一项上差一点系数。
推推式子就可以通过 Q i ( x ) Q_i(x) Qi(x)推出其整式递推式。
2.必要性:
发现 A ( i ) ( x ) A^{(i)}(x) A(i)(x)其实和 A ( x ) x − i A(x)x^{-i} A(x)xi就是每一项上差一点系数。
推推式子就可以通过 P i ( x ) P_i(x) Pi(x)推出使其满足微分有限的有限多项式序列 Q i ( x ) Q_i(x) Qi(x)
(不是伪证吧。)

代数形式幂级数均为微分有限的。
)证明:
引理:考虑多项式向量(更严谨的说法是:多项式构成了一个向量空间。)
那么 A ( x ) A(x) A(x)的任意导数那么多个多项式,他们构成的向量空间维数有限,假设为 k k k,那么对于 A ( x ) , A ′ ( x ) , A ′ ′ ( x ) . . . A ( k ) ( x ) A(x),A'(x),A''(x)...A^{(k)}(x) A(x),A(x),A(x)...A(k)(x)他们这 k + 1 k+1 k+1个向量(多项式)就一定线性相关,可以给出一个他们的线性组合 Q i ( x ) Q_i(x) Qi(x)使得 ∑ i = 0 k Q i ( x ) A ( i ) ( x ) = 0 \sum_{i=0}^k Q_i(x)A^{(i)}(x)=0 i=0kQi(x)A(i)(x)=0

首先对于简单的 f ( x ) = x f(x)=x f(x)=x之类的我们可以 (由上一条引理)显然发现他们是微分有限的。

然后我们可以得到对于微分有限形式幂级数 u ( x ) u(x) u(x)和代数形式幂级数 v ( x ) v(x) v(x) u ( v ( x ) ) u(v(x)) u(v(x))在其常数项收敛的意义下(形式幂级数复合常数项不收敛就构不成形式幂级数),也是微分有限的,然后就可以数归地证明所有形式幂级数均为微分有限的。

应用层面:
求出一个数列的整式递推式。
在这里插入图片描述
感觉,。;

例题:
在这里插入图片描述
首先我们可以得到一个 O ( n 5 ) O(n^5) O(n5)左右的大力 D P DP DP
在这里插入图片描述
然后打出表来之后我们可以。
去这里白嫖zzq的模板
然后求出 n < = 1 e 6 n<=1e6 n<=1e6的范围的答案。
。。。
参考代码:

#include<bits/stdc++.h>
#define mod 998244353
#define LL long long
#define rep(i,j,k) for(int i=(j),LIM=(k);i<=LIM;i++) 
using namespace std;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; }
vector<vector<int> > find_rel(
const vector<int>& ini,int deg)
{int n=ini.size(),B=(n+2)/(deg+2),C=B*(deg+1),R=n-(B-1);assert(B>=2&&R>=C-1);vector<vector<int> > mat(R,vector<int>(C));for(int i=0;i<R;++i)for(int j=0;j<B;++j)for(int k=0,x=ini[i+j]%mod;k<=deg;++k)mat[i][j*(deg+1)+k]=x,x=x*(LL)(i+j)%mod;int c=0;for(int i=0;i<C;++i){int p=-1;for(int j=c;j<R;++j) if(mat[j][i]) {p=j; break;}if(p==-1) break;swap(mat[p],mat[c]);LL w=Pow(mat[c][c],mod-2);for(int j=i;j<C;++j) mat[c][j]=mat[c][j]*w%mod;for(int j=c+1;j<R;++j) if(mat[j][i]) //not fully eliminated{LL t=mat[j][i];for(int k=i;k<C;++k)mat[j][k]=(mat[j][k]-mat[i][k]*t)%mod;}++c;}assert(c!=C);for(int i=c-1;i>=0;--i) if(mat[i][c])for(int j=i-1;j>=0;--j)mat[j][c]=(mat[j][c]-mat[i][c]*(LL)mat[j][i])%mod;int od=c/(deg+1);vector<vector<int> > ret(od+1,vector<int>(deg+1));ret[0][c%(deg+1)]=1;for(int i=c-1;i>=0;--i)ret[od-i/(deg+1)][i%(deg+1)]=-mat[i][c];for(int i=0;i<=od;++i){vector<int> tmp(deg+1);for(int k=0;k<=deg;++k){LL S=1;for(int j=k;j<=deg;++j)tmp[k]=(tmp[k]+S*ret[i][j])%mod,S=S*(-i)%mod*(j+1)%mod*Pow(j+1-k,mod-2)%mod;tmp[k]=(tmp[k]%mod+mod)%mod;}ret[i]=tmp;}return ret;
}
int a[4][100005]={{0,0,1,9,55,290,1418,6629,30091,133806,586054,2537370,10886566,46369284,196323476,827082029,474985712,528106312,541758386,595828051,59377087,109000449,755534195,558578043,332657763,629563085,615306569,60402678,105929548,493601184,189333986,389953147,797915382,481229189,420292720,995685669,560845133,516975474,972593286,537377753,364690619,508809028,207371388,387442055,595552026,675655967,43409867,610503018,995841202,883699315,167313459}, {0,0,0,0,14,149,1054,6236,33398,167990,809664,3784560,17289420,77603161,343494418,-493097854,-468248033,104095918,157010208,-115880831,831488755,64373852,112711345,-491592039,-127489852,-177098602,-266045469,233150578,-12173954,294233090,-187126183,134746385,-321149993,-148345218,465153584,-44795846,-533979392,-305848929,-28957884,-253196987,539610500,-254944522,505585010,450780534,-246076482,-32472303,811346038,-265758912,-670036911,-362311751,634820484}, {0,0,0,0,3,98,1074,8245,52812,303340,1621010,8232983,40276667,191487706,-107998677,72391037,327327922,-507090862,-311407461,258624519,-561066175,365152019,-692593286,66360168,507909062,381762652,-248265301,351446733,647281286,-537110773,629992197,-93817477,-406946020,-79571376,-482899551,-44057130,820178765,637207205,-889827567,12730960,-400770744,-237003144,182901450,-795696960,321057984,-451718838,-436709246,353485690,563895810,126132164,-671112947}, {0,0,0,0,0,21,484,5430,44472,304997,1867456,10573956,56564788,289885815,438658583,946463028,822984448,341838670,633606596,893811591,27160201,979478338,875209020,580102669,528317334,663671805,285229136,454142107,887552094,642070688,437542901,898440781,100405302,511509010,392851051,161580714,175762226,863850977,529597727,669267529,559836197,946462699,428001404,55115645,513632905,181210615,146227845,802185240,453391893,421254118,891837190} };
vector<int>v[4]={vector<int>(a[0],a[0]+50),vector<int>(a[1],a[1]+50),vector<int>(a[2],a[2]+50),vector<int>(a[3],a[3]+50)};int main(){int n,m;scanf("%d%d",&n,&m);vector<vector<int> >r=find_rel(v[m],7);printf("%d\n",r.size());rep(i,49,n){int s=0;rep(k,1,r.size()-1){vector<int>&u=r[k];int t=1;rep(j,0,u.size()-1){s=(s-1ll*t*a[m][i-k]%mod*u[j])%mod;t=1ll*t*i%mod;}}vector<int>&u=r[0];int t=1,sm=0;rep(j,0,u.size()-1){sm=(sm+1ll*t*u[j])%mod;t=1ll*t*i%mod;	}a[m][i]=Pow(sm,mod-2)*1ll*s%mod;}printf("%d\n",(a[m][n]+mod)%mod);
}

留tag:这个模板我想把它压到20行以内,
但是我不懂它在写些什么。。。

所以,今天开始啃Enumerative Combinatorics Volume 2:第6章。
在这里插入图片描述
这是有理分式的定义,指一个形式幂级数可以被表示为一个一次幂级数方程的根。
在这里插入图片描述
所以有理分式域就是拓展拉格朗日反演证明里那个奇怪的域?
在这里插入图片描述
来啦来啦代数形式幂级数、
在这里插入图片描述
开始了, D − f i n i t e D-finite Dfinite微分有限 P − r e c u r s i v e P-recursive Precursive多项式递归函数大赏。
在这里插入图片描述

但是 u 1 , u 2 , u 4 u_1,u_2,u_4 u1,u2,u4不是 D − f i n i t e D-finite Dfinite的。。。
在这里插入图片描述
复合法则。

撒花!
终于压进20行了。
顺便说下 z z q zzq zzq那不觉明历的写法是什么意思。
首先我们需要把待定的整式递推式倒过来写(论文应该是打错了字),建立每个 a i a_i ai和之后若干 ( B − 1 B-1 B1)个的整式方程,于是形如 ∑ i = 0 B − 1 a k + i Q B − 1 − i = 0 \sum_{i=0}^{B-1} a_{k+i}Q_{B-1-i}=0 i=0B1ak+iQB1i=0,这是因为我们不知道求出的最短整式递推式长度是多少,换成从前到后的形式可以保证不管求出的整式递推式长度为多少,对于前面几项它都应该是满足的,如果从后往前那么就有不满足前面几项的可能。
然后就直接高斯消元?
但是你要发现,我们这些方程的右边都是 0 0 0
稍微学学线性代数的入门课程即可发现,我们需要的是一个非平凡解(就是非全 0 0 0解),而在这种方程组中非平凡解存在就必须要有自由元,其构成的矩阵不满秩。
那么我们按翻转后的 Q Q Q数组从前往后高斯消元,那么得到一个自由元时,前面的子矩阵就是最小的不满秩前缀矩阵(语无伦次)。
那么我们把这个最小的不满秩前缀矩阵,令其中唯一的自由元为1。
注意这个自由元对应在 ∑ i = 0 B − 1 a k + i Q B − 1 − i = 0 \sum_{i=0}^{B-1} a_{k+i}Q_{B-1-i}=0 i=0B1ak+iQB1i=0中应该是 Q 0 Q_0 Q0中的一个 x k x^k xk前的系数。
这时把前面的元都解出来可以得到 Q Q Q,再二项式定理得到 P P P即可。
注意这时求出的很有可能是该次数下最小阶的(最短的)。
可能求出多个阶数不同的整式递推式,但是阶数变短是需要次数提升作为代价的。
另外模板里确定 B B B的那个奇怪的式子是 M i n 25 \mathrm{\color{black}M\color{red}in_{25}} Min25提出来的。(我也不太懂日语)
在这里插入图片描述

20行模板:

#include<bits/stdc++.h>
#define mod 998244353
#define LL long long
#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 vc vector
#define vi vc<int>
#define Ct const
using namespace std;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; }
vc<vi>PR(Ct vi &a,int D){ // P-recursive , a[0~a.size()-1] is usdint N=a.size(),B=(N+2)/(D+2),C=B*(D+1),R=N-(B-1),c;vc<vi>b(R,vi(C));rep(i,0,R-1) rep(j,0,B-1) for(int k=0,pw=a[i+j];k<=D;k++,pw=(LL)pw*i%mod) b[i][j*(D+1)+k]=pw;rep(i,0,C-1){int p=-1;rep(j,i,R-1) if(b[j][i]) {p=j;break;}if(p==-1){ c=i;break;}swap(b[i],b[p]);p=Pow(b[i][i],mod-2);rep(j,i,C-1) b[i][j]=(LL)b[i][j]*p%mod;rep(j,i+1,R-1) if(p=b[j][i]) rep(k,i,C-1) b[j][k]=(b[j][k]-(LL)b[i][k]*p)%mod; }assert(c^C);int M=c/(D+1)+1;per(i,c-1,0) if(b[i][c]) rep(j,0,i-1) b[j][c]=(b[j][c]-(LL)b[j][i]*b[i][c])%mod;vc<vi>r(M,vi(D+1));vi t(D+1);rep(i,(r[0][c%(D+1)]=1,0),c-1) r[M-i/(D+1)-1][i%(D+1)]=-b[i][c];for(int i=0,S;i<M;r[i]=t,t=vi(D+1),i++)rep(j,0,D) rep(k,(S=1,j),D){t[j]=(t[j]+(LL)S*r[i][k])%mod;S=(LL)S*(-M+1)%mod*(k+1)%mod*Pow(k-j+1,mod-2)%mod;}return r;
}

快速求整式递推数列的第 n n n项:
看洛谷的【模板】整式递推


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

相关文章

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

头歌实验&#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;其中每个方块用空白表示通道…