首先我们对整个平面做线性变换:
(x,y)→(x,x−y)。这样就变成了从
(0,0) 移动到
(n,0) 且不越过
y=0 这条线,方便我们描述一些。
现在就有一个简单的 DP,给定
f0(z)=1,以及递推式
fk(z)=1−z1∑i=0kai(fk−i(1)−zifk−i(z))
(含义:如果
x 选择走
ai 长度,那么第二维可以
走到 y+ai−1 以内的任意自然数)
尝试求出
fn(0)。建立二元 GF 就有方程
(1−z)F(z,t)=A(t)F(1,t)−A(tz)F(z,t)+1−z
由此也能得到
F(z,t)=1−z+A(tz)A(t)F(1,t)+1−z
而我们知道
[zn+1]F(z,t)≡0(modtn+1)(没法走到这么高),根据这一点可以解出
F(1,t)。设
gk(t)=[zk]1−z+A(tz)1
则
F(0,t)≡A(t)F(1,t)+1≡gn+1(t)gn(t)(modtn+1)
那么问题就变为如何快速计算
gk(t) 了...吗?直接计算
gk(t) 可能比较困难,如果能直接计算两项之比就好了。大家一定知道 Fibonacci 数相邻两项之比的极限吧:
limn→∞fn+1fn=25−1
它等于
fn 递推式中,模长最大的特征根的倒数。显然
gn(t)/gn+1(t) 的极限也是存在的,我们尝试用类似的方法处理。显然我们先验地知道这个极限的常数项为
1,且不存在负次项,这将给后续推导提供重要帮助。
考虑到特征方程
zn(1−z−1+A(t/z)) 有多达
n 个根难以处理,但既然
gn(t)/gn+1(t) 的极限已经确定了最低非零项,那么我们只需要找出特征方程中也满足相同性质的那个根即可。
也就是说,我们要找一个形式幂级数
F(t),满足
F(0)=1,且
F(t)n(1−1/F(t)+A(t/F(t)))=0
(很幸运,满足条件的
F(t) 是唯一的)
那么答案即为
[tn]1/F(t)。
稍微化简一下,设
G(t)=1/F(t),则方程变为
1−G(t)+A(tG(t))=0
t=tG(t)−tA(tG(t))
所求的答案也变为
[tn+1]tG(t)。令
H(t) 为
tG(t) 的复合逆,则
H(t)=t−H(t)A(t),答案也就是
[tn+1]tG(t)=n+11[xn](H(t)t)n+1=n+11[tn](1+A(t))n+1
完全胜利!