简介
常系数齐次线性递推数列(又称为 C-finite 或 C-recursive 数列)是常见的一类基础的递推数列.
对于数列 ( a j ) j ≥ 0 \left(a_j\right)_{j\geq 0} ( a j ) j ≥ 0 和其递推式
a n = ∑ j = 1 d c j a n − j , ( n ≥ d ) a_n=\sum_{j=1}^{d}c_ja_{n-j},\qquad (n\geq d) a n = j = 1 ∑ d c j a n − j , ( n ≥ d )
其中 c j c_j c j 不全为零,我们的目标是在给出初值 a 0 , … , a d − 1 a_0,\dots ,a_{d-1} a 0 , … , a d − 1 和递推式中的 c 1 , … , c d c_1,\dots ,c_d c 1 , … , c d 后求出 a k a_k a k .如果 k ≫ d k\gg d k ≫ d ,我们想要更快速的算法.
这里 ( a j ) j ≥ 0 \left(a_j\right)_{j\geq 0} ( a j ) j ≥ 0 被称为 d d d 阶的常系数齐次线性递推数列.
Fiduccia 算法
Fiduccia 算法使用多项式取模和快速幂来计算 a k a_k a k ,时间为 O ( M ( d ) log k ) O(\mathsf{M}(d)\log k) O ( M ( d ) log k ) ,其中 O ( M ( d ) ) O(\mathsf{M}(d)) O ( M ( d )) 表示两个次数为 O ( d ) O(d) O ( d ) 的多项式相乘的时间.
算法 :构造多项式 Γ ( x ) : = x d − ∑ j = 0 d − 1 c d − j x j \Gamma(x):=x^d-\sum_{j=0}^{d-1}c_{d-j}x^j Γ ( x ) := x d − ∑ j = 0 d − 1 c d − j x j 和 A ( x ) : = ∑ j = 0 d − 1 a j x j A(x):=\sum_{j=0}^{d-1}a_jx^j A ( x ) := ∑ j = 0 d − 1 a j x j ,那么
a k = ⟨ x k m o d Γ ( x ) , A ( x ) ⟩ a_k=\left\langle x^k\bmod{\Gamma(x)},A(x)\right\rangle a k = ⟨ x k mod Γ ( x ) , A ( x ) ⟩
其中定义 ⟨ ( ∑ j = 0 n − 1 f j x j ) , ( ∑ j = 0 n − 1 g j x j ) ⟩ : = ∑ j = 0 n − 1 f j g j \left\langle \left(\sum_{j=0}^{n-1}f_jx^j\right),\left(\sum_{j=0}^{n-1}g_jx^j\right) \right\rangle :=\sum_{j=0}^{n-1}f_jg_j ⟨ ( ∑ j = 0 n − 1 f j x j ) , ( ∑ j = 0 n − 1 g j x j ) ⟩ := ∑ j = 0 n − 1 f j g j 为内积.
证明 :我们定义 Γ ( x ) \Gamma(x) Γ ( x ) 的友矩阵为
C Γ : = [ c d 1 c d − 1 ⋱ ⋮ 1 c 1 ] C_\Gamma:=
\begin{bmatrix}
&&&c_d \\
1&&&c_{d-1} \\
&\ddots &&\vdots \\
&&1&c_1
\end{bmatrix} C Γ := 1 ⋱ 1 c d c d − 1 ⋮ c 1
我们定义多项式 b ( x ) : = ∑ j = 0 d − 1 b j x j b(x):=\sum_{j=0}^{d-1}b_jx^j b ( x ) := ∑ j = 0 d − 1 b j x j 和
B b : = [ b 0 b 1 ⋯ b d − 1 ] ⊺ B_b:=\begin{bmatrix}b_0&b_1&\cdots &b_{d-1}\end{bmatrix}^{\intercal} B b := [ b 0 b 1 ⋯ b d − 1 ] ⊺
观察到
[ c d 1 c d − 1 ⋱ ⋮ 1 c 1 ] ⏟ C Γ [ b 0 b 1 ⋮ b d − 1 ] ⏟ B b = [ c d b d − 1 b 0 + c d − 1 b d − 1 ⋮ b d − 2 + c 1 b d − 1 ] ⏟ B x b m o d Γ \underbrace{\begin{bmatrix}
&&&c_d \\
1&&&c_{d-1} \\
&\ddots &&\vdots \\
&&1&c_1
\end{bmatrix}}_{C_\Gamma}
\underbrace{\begin{bmatrix}
b_0 \\
b_1 \\
\vdots \\
b_{d-1}
\end{bmatrix}}_{B_b}=
\underbrace{\begin{bmatrix}
c_db_{d-1} \\
b_0+c_{d-1}b_{d-1} \\
\vdots \\
b_{d-2}+c_1b_{d-1}
\end{bmatrix}} _ {B_{xb\bmod{\Gamma}}} C Γ 1 ⋱ 1 c d c d − 1 ⋮ c 1 B b b 0 b 1 ⋮ b d − 1 = B x b mod Γ c d b d − 1 b 0 + c d − 1 b d − 1 ⋮ b d − 2 + c 1 b d − 1
且
C Γ = [ B x m o d Γ B x 2 m o d Γ ⋯ B x d m o d Γ ] , ( C Γ ) 2 = [ B x 2 m o d Γ B x 3 m o d Γ ⋯ B x d + 1 m o d Γ ] , ⋯ ( C Γ ) k = [ B x k m o d Γ B x k + 1 m o d Γ ⋯ B x k + d m o d Γ ] \begin{aligned}
C_\Gamma&=\begin{bmatrix}B_{x\bmod{\Gamma}}&B_{x^2\bmod{\Gamma}}&\cdots &B_{x^d\bmod{\Gamma}}\end{bmatrix}, \\
\left(C_\Gamma\right)^2&=\begin{bmatrix}B_{x^2\bmod{\Gamma}}&B_{x^3\bmod{\Gamma}}&\cdots &B_{x^{d+1}\bmod{\Gamma}}\end{bmatrix}, \\
\cdots \\
\left(C_\Gamma\right)^k&=\begin{bmatrix}B_{x^k\bmod{\Gamma}}&B_{x^{k+1}\bmod{\Gamma}}&\cdots &B_{x^{k+d}\bmod{\Gamma}}\end{bmatrix}
\end{aligned} C Γ ( C Γ ) 2 ⋯ ( C Γ ) k = [ B x mod Γ B x 2 mod Γ ⋯ B x d mod Γ ] , = [ B x 2 mod Γ B x 3 mod Γ ⋯ B x d + 1 mod Γ ] , = [ B x k mod Γ B x k + 1 mod Γ ⋯ B x k + d mod Γ ]
我们将这个递推用矩阵表示有
[ a k a k + 1 ⋮ a k + d − 1 ] = [ 1 ⋱ 1 c d c d − 1 ⋯ c 1 ] k ⏟ ( ( C Γ ) ⊺ ) k = ( ( C Γ ) k ) ⊺ [ a 0 a 1 ⋮ a d − 1 ] \begin{bmatrix}
a_{k} \\
a_{k+1} \\
\vdots \\
a_{k+d-1}
\end{bmatrix}=\underbrace{\begin{bmatrix}
&1&& \\
&&\ddots & \\
&&&1 \\
c_d&c_{d-1}&\cdots &c_1
\end{bmatrix}^k} _ {\left(\left(C_\Gamma\right)^{\intercal}\right)^k=\left(\left(C_\Gamma\right)^{k}\right)^{\intercal}}
\begin{bmatrix}
a_0 \\
a_{1} \\
\vdots \\
a_{d-1}
\end{bmatrix} a k a k + 1 ⋮ a k + d − 1 = ( ( C Γ ) ⊺ ) k = ( ( C Γ ) k ) ⊺ c d 1 c d − 1 ⋱ ⋯ 1 c 1 k a 0 a 1 ⋮ a d − 1
可知 ( ( C Γ ) k ) ⊺ \left(\left(C_\Gamma\right)^{k}\right)^{\intercal} ( ( C Γ ) k ) ⊺ 的第一行为 B x k m o d Γ B_{x^k\bmod{\Gamma}} B x k mod Γ ,根据矩阵乘法的定义得证.
表示为有理函数
对于上述数列 ( a j ) j ≥ 0 \left(a_j\right)_{j\geq 0} ( a j ) j ≥ 0 一定存在有理函数
P ( x ) Q ( x ) = ∑ j ≥ 0 a j x j \frac{P(x)}{Q(x)}=\sum_{j\geq 0}a_jx^j Q ( x ) P ( x ) = j ≥ 0 ∑ a j x j
且 Q ( x ) = x d Γ ( x − 1 ) Q(x)=x^d\Gamma\left(x^{-1}\right) Q ( x ) = x d Γ ( x − 1 ) ,deg P < d \deg{P}<d deg P < d .我们称其为「有理函数 」是因为 P ( x ) , Q ( x ) P(x),Q(x) P ( x ) , Q ( x ) 是「多项式 」.
证明 :对于 P ( x ) = ∑ j = 0 d − 1 p j x j P(x)=\sum_{j=0}^{d-1}p_jx^j P ( x ) = ∑ j = 0 d − 1 p j x j 和 Q ( x ) : = ∑ j = 0 d q j x j Q(x):=\sum_{j=0}^{d}q_jx^j Q ( x ) := ∑ j = 0 d q j x j 考虑 P ( x ) Q ( x ) = ∑ j ≥ 0 q ~ j x j \dfrac{P(x)}{Q(x)}=\sum_{j\geq 0}\tilde{q}_jx^j Q ( x ) P ( x ) = ∑ j ≥ 0 q ~ j x j 的系数定义,这几乎就是形式幂级数「除法 」的定义,
q ~ N = { p 0 q 0 − 1 , if N = 0 , ( p N − ∑ j = 1 N q j q ~ N − j ) ⋅ q 0 − 1 , else if N < d , − q 0 − 1 ∑ j = 1 d q j q ~ N − j , otherwise . \tilde{q}_N=
\begin{cases}
p_0q_0^{-1},&\text{ if }N=0, \\
\left(p_N-\sum_{j=1}^{N}q_j\tilde{q}_{N-j}\right)\cdot q_0^{-1},&\text{ else if }N<d, \\
-q_0^{-1}\sum_{j=1}^{d}q_j\tilde{q}_{N-j},&\text{ otherwise}.
\end{cases} q ~ N = ⎩ ⎨ ⎧ p 0 q 0 − 1 , ( p N − ∑ j = 1 N q j q ~ N − j ) ⋅ q 0 − 1 , − q 0 − 1 ∑ j = 1 d q j q ~ N − j , if N = 0 , else if N < d , otherwise .
我们只需要令
P ( x ) = ( ( ∑ j ≥ 0 a j x j ) ⋅ x d Γ ( x − 1 ) ) m o d x d P(x)=\left(\left(\sum_{j\geq 0}a_jx^j\right)\cdot x^d\Gamma\left(x^{-1}\right)\right)\bmod{x^d} P ( x ) = ( ( j ≥ 0 ∑ a j x j ) ⋅ x d Γ ( x − 1 ) ) mod x d
那么根据 q ~ N \tilde{q}_N q ~ N 的定义,必然有 P ( x ) Q ( x ) = ∑ j ≥ 0 a j x j \dfrac{P(x)}{Q(x)}=\sum_{j\geq 0}a_jx^j Q ( x ) P ( x ) = ∑ j ≥ 0 a j x j .
Bostan–Mori 算法
计算单项
我们的目标仍然是给出上述多项式 P ( x ) , Q ( x ) P(x),Q(x) P ( x ) , Q ( x ) ,求算 [ x k ] P ( x ) Q ( x ) \left\lbrack x^k\right\rbrack\dfrac{P(x)}{Q(x)} [ x k ] Q ( x ) P ( x ) .
Bostan–Mori 算法基于 Graeffe 迭代,对于上述多项式 P ( x ) , Q ( x ) P(x),Q(x) P ( x ) , Q ( x ) 有
P ( x ) Q ( x ) = P ( x ) Q ( − x ) Q ( x ) Q ( − x ) = U 0 ( x 2 ) + x U 1 ( x 2 ) V ( x 2 ) \frac{P(x)}{Q(x)}=\frac{P(x)Q(-x)}{Q(x)Q(-x)}=\frac{U_0(x^2)+xU_1(x^2)}{V(x^2)} Q ( x ) P ( x ) = Q ( x ) Q ( − x ) P ( x ) Q ( − x ) = V ( x 2 ) U 0 ( x 2 ) + x U 1 ( x 2 )
因为分母 V ( x 2 ) V(x^2) V ( x 2 ) 是偶函数,所以子问题只需考虑其中的一侧
[ x k ] P ( x ) Q ( x ) = [ x ⌊ k / 2 ⌋ ] U k m o d 2 ( x ) V ( x ) \left\lbrack x^k\right\rbrack\dfrac{P(x)}{Q(x)}=\left\lbrack x^{\left\lfloor k/2\right\rfloor}\right\rbrack \frac{U_{k\bmod{2}}(x)}{V(x)} [ x k ] Q ( x ) P ( x ) = [ x ⌊ k /2 ⌋ ] V ( x ) U k mod 2 ( x )
我们付出两次多项式乘法的代价使得问题至少减少为原先的一半,而当 k = 0 k=0 k = 0 时显然有 [ x 0 ] P ( x ) Q ( x ) = P ( 0 ) Q ( 0 ) \left\lbrack x^0\right\rbrack \dfrac{P(x)}{Q(x)}=\dfrac{P(0)}{Q(0)} [ x 0 ] Q ( x ) P ( x ) = Q ( 0 ) P ( 0 ) ,时间复杂度同上.
计算连续若干项
目标是给出上述多项式 P ( x ) , Q ( x ) P(x),Q(x) P ( x ) , Q ( x ) ,求算 [ x [ L , R ) ] P ( x ) Q ( x ) \left\lbrack x^{\left\lbrack L,R\right)}\right\rbrack\dfrac{P(x)}{Q(x)} [ x [ L , R ) ] Q ( x ) P ( x ) .下面的计算中我们只需考虑对答案「有影响 」的系数,这是 Bostan–Mori 算法的关键.
我们不妨假设 deg P < deg Q \deg{P}<\deg{Q} deg P < deg Q ,否则我们也可以通过一次带余除法使问题回到这种情况.
我们先考虑更简单的问题:
[ x [ L , R ) ] 1 Q ( x ) = [ x [ L , R ) ] 1 Q ( x ) Q ( − x ) ⋅ Q ( − x ) \left\lbrack x^{\left\lbrack L,R\right)}\right\rbrack\frac{1}{Q(x)}=\left\lbrack x^{\left\lbrack L,R\right)}\right\rbrack\frac{1}{Q(x)Q(-x)}\cdot Q(-x) [ x [ L , R ) ] Q ( x ) 1 = [ x [ L , R ) ] Q ( x ) Q ( − x ) 1 ⋅ Q ( − x )
我们需要求出 [ x [ L − deg Q , R ) ] 1 Q ( x ) Q ( − x ) \left\lbrack x^{\left\lbrack L-\deg{Q},R\right)}\right\rbrack\dfrac{1}{Q(x)Q(-x)} [ x [ L − d e g Q , R ) ] Q ( x ) Q ( − x ) 1 然后作一次乘法并取出 x L , … , x R − 1 x^L,\dots ,x^{R-1} x L , … , x R − 1 的系数.令 V ( x 2 ) = Q ( x ) Q ( − x ) V(x^2)=Q(x)Q(-x) V ( x 2 ) = Q ( x ) Q ( − x ) 那么我们只需求出
[ x [ ⌈ L − deg Q 2 ⌉ , ⌈ R 2 ⌉ ) ] 1 V ( x ) \left\lbrack x^{\left\lbrack \left\lceil\frac{L-\deg{Q}}{2}\right\rceil,\left\lceil\frac{R}{2}\right\rceil\right)}\right\rbrack\frac{1}{V(x)} [ x [ ⌈ 2 L − d e g Q ⌉ , ⌈ 2 R ⌉ ) ] V ( x ) 1
就可以还原出 [ x [ L − deg Q , R ) ] 1 Q ( x ) Q ( − x ) \left\lbrack x^{\left\lbrack L-\deg{Q},R\right)}\right\rbrack\dfrac{1}{Q(x)Q(-x)} [ x [ L − d e g Q , R ) ] Q ( x ) Q ( − x ) 1 .进而我们只需求出 [ x [ L − deg P , R ) ] 1 Q ( x ) \left\lbrack x^{\left\lbrack L-\deg{P},R\right)}\right\rbrack\dfrac{1}{Q(x)} [ x [ L − d e g P , R ) ] Q ( x ) 1 再和 P ( x ) P(x) P ( x ) 作一次乘法即可求出 [ x [ L , R ) ] P ( x ) Q ( x ) \left\lbrack x^{\left\lbrack L,R\right)}\right\rbrack\dfrac{P(x)}{Q(x)} [ x [ L , R ) ] Q ( x ) P ( x ) .
上面的算法虽然已经可以工作,但是每一次的递归的时间复杂度与 R − L R-L R − L 相关,我们希望能至少在递归求算时摆脱 R − L R-L R − L ,更具体的,我们先考虑求算 [ x [ L , L + deg Q + 1 ) ] 1 Q ( x ) \left\lbrack x^{\left\lbrack L,L+\deg Q+1\right)}\right\rbrack \dfrac{1}{Q(x)} [ x [ L , L + d e g Q + 1 ) ] Q ( x ) 1 ,考虑
[ x [ L , L + deg Q + 1 ) ] 1 Q ( x ) = [ x [ L , L + deg Q + 1 ) ] 1 Q ( x ) Q ( − x ) ⋅ Q ( − x ) \left\lbrack x^{\left\lbrack L,L+\deg Q+1\right)}\right\rbrack \frac{1}{Q(x)}=\left\lbrack x^{\left\lbrack L,L+\deg Q+1\right)}\right\rbrack \dfrac{1}{Q(x)Q(-x)}\cdot Q(-x) [ x [ L , L + d e g Q + 1 ) ] Q ( x ) 1 = [ x [ L , L + d e g Q + 1 ) ] Q ( x ) Q ( − x ) 1 ⋅ Q ( − x )
我们需要求出
[ x [ L − deg Q , L + deg Q + 1 ) ] 1 Q ( x ) Q ( − x ) \left\lbrack x^{\left\lbrack L-\deg Q,L+\deg Q+1\right)}\right\rbrack \dfrac{1}{Q(x)Q(-x)} [ x [ L − d e g Q , L + d e g Q + 1 ) ] Q ( x ) Q ( − x ) 1
那么对于 V ( x 2 ) = Q ( x ) Q ( − x ) V(x^2)=Q(x)Q(-x) V ( x 2 ) = Q ( x ) Q ( − x ) 而言,我们只需求出
[ x [ ⌈ ( L − deg Q ) / 2 ⌉ , ⌈ ( L + deg Q + 1 ) / 2 ⌉ ) ] 1 V ( x ) \left\lbrack x^{\left\lbrack \lceil (L-\deg Q)/2 \rceil,\lceil (L+\deg Q+1)/2 \rceil\right)}\right\rbrack \frac{1}{V(x)} [ x [ ⌈( L − d e g Q ) /2 ⌉ , ⌈( L + d e g Q + 1 ) /2 ⌉ ) ] V ( x ) 1
这是因为
[ x k ] 1 Q ( x ) Q ( − x ) = { [ x k / 2 ] 1 V ( x ) , if k ≡ 0 ( m o d 2 ) , 0 , otherwise . \left\lbrack x^{k}\right\rbrack\dfrac{1}{Q(x)Q(-x)}=
\begin{cases}
\left\lbrack x^{k/2}\right\rbrack\dfrac{1}{V(x)},&\text{if }k\equiv 0\pmod{2}, \\
0,&\text{otherwise}.
\end{cases} [ x k ] Q ( x ) Q ( − x ) 1 = ⎩ ⎨ ⎧ [ x k /2 ] V ( x ) 1 , 0 , if k ≡ 0 ( mod 2 ) , otherwise .
我们知道 L + deg Q L+\deg Q L + deg Q 和 L − deg Q L-\deg Q L − deg Q 的奇偶性是一样的,所以
⌈ L + deg Q + 1 2 ⌉ − ⌈ L − deg Q 2 ⌉ = { deg Q + 1 , if L + deg Q ≡ 0 ( m o d 2 ) , deg Q , otherwise . \left\lceil \frac{L+\deg Q+1}{2}\right\rceil -\left\lceil \frac{L-\deg Q}{2}\right\rceil =
\begin{cases}
\deg Q+1,&\text{if }L+\deg Q\equiv 0\pmod{2}, \\
\deg Q,&\text{otherwise}.
\end{cases} ⌈ 2 L + deg Q + 1 ⌉ − ⌈ 2 L − deg Q ⌉ = { deg Q + 1 , deg Q , if L + deg Q ≡ 0 ( mod 2 ) , otherwise .
这样我们可以写出伪代码
Algorithm Slice-Coefficients ( Q , L ) : Input : Q ( x ) ∈ C [ x ] , L ∈ Z . Output : [ x [ L , L + deg Q + 1 ) ] Q ( x ) − 1 . 1 if L ≤ 1 then return [ x [ L , L + deg Q + 1 ) ] Q ( x ) − 1 Use other algorithm to compute Q ( x ) − 1 2 V ( x 2 ) ← Q ( x ) Q ( − x ) 3 k ← ⌈ L − deg Q 2 ⌉ 4 ( t k , … , t k + deg Q ) ← Slice-Coefficients ( V , k ) 5 T ( x ) ← x ( L − deg Q ) m o d 2 ∑ j = 0 deg Q t j + k x 2 j 6 return [ x [ deg Q , 2 deg Q + 1 ) ] T ( x ) Q ( − x ) \begin{array}{ll}
&\textbf{Algorithm }\operatorname{Slice-Coefficients}(Q,L)\text{:} \\
&\textbf{Input}\text{: }Q(x)\in\mathbb{C}\left\lbrack x\right\rbrack,L\in\mathbb{Z}\text{.} \\
&\textbf{Output}\text{: }\left\lbrack x^{\left\lbrack L,L+\deg Q+1\right)}\right\rbrack Q(x)^{-1}\text{.} \\
1&\textbf{if }L\leq 1\textbf{ then return }\left\lbrack x^{\left\lbrack L,L+\deg Q+1\right)}\right\rbrack Q(x)^{-1} \\
&\text{Use other algorithm to compute }Q(x)^{-1} \\
2&V(x^2)\gets Q(x)Q(-x) \\
3&k\gets \left\lceil \frac{L-\deg Q}{2}\right\rceil \\
4&(t_k,\dots ,t_{k+\deg Q})\gets \operatorname{Slice-Coefficients}\left(V,k\right) \\
5&T(x)\gets x^{(L-\deg Q)\bmod{2}}\sum_{j=0}^{\deg Q}t_{j+k}x^{2j} \\
6&\textbf{return }\left\lbrack x^{\left\lbrack \deg Q,2\deg Q+1\right)}\right\rbrack T(x)Q(-x)
\end{array} 1 2 3 4 5 6 Algorithm Slice-Coefficients ( Q , L ) : Input : Q ( x ) ∈ C [ x ] , L ∈ Z . Output : [ x [ L , L + d e g Q + 1 ) ] Q ( x ) − 1 . if L ≤ 1 then return [ x [ L , L + d e g Q + 1 ) ] Q ( x ) − 1 Use other algorithm to compute Q ( x ) − 1 V ( x 2 ) ← Q ( x ) Q ( − x ) k ← ⌈ 2 L − d e g Q ⌉ ( t k , … , t k + d e g Q ) ← Slice-Coefficients ( V , k ) T ( x ) ← x ( L − d e g Q ) mod 2 ∑ j = 0 d e g Q t j + k x 2 j return [ x [ d e g Q , 2 d e g Q + 1 ) ] T ( x ) Q ( − x )
但是只有这个算法还不够,我们需要重新找到一个有理函数并求算更多系数.
找到新的有理函数表示
我们知道 Q ( x ) Q(x) Q ( x ) 本身和 Q ( x ) − 1 Q(x)^{-1} Q ( x ) − 1 的一部分连续的系数比如 [ x [ L , L + deg Q ) ] Q ( x ) − 1 \left\lbrack x^{\left\lbrack L,L+\deg Q\right)}\right\rbrack Q(x)^{-1} [ x [ L , L + d e g Q ) ] Q ( x ) − 1 和 L ≥ 0 L\geq 0 L ≥ 0 ,我们希望求出 [ x [ L + deg Q , L + 2 deg Q ) ] Q ( x ) − 1 \left\lbrack x^{\left\lbrack L+\deg Q,L+2\deg Q\right)}\right\rbrack Q(x)^{-1} [ x [ L + d e g Q , L + 2 d e g Q ) ] Q ( x ) − 1 ,这等价于我们要求某个 P ( x ) P(x) P ( x ) 且 deg P < deg Q \deg P< \deg Q deg P < deg Q 使得 P ( x ) Q ( x ) \dfrac{P(x)}{Q(x)} Q ( x ) P ( x ) 的前 deg Q \deg Q deg Q 项与 [ x [ L , L + deg Q ) ] Q ( x ) − 1 \left\lbrack x^{\left\lbrack L,L+\deg Q\right)}\right\rbrack Q(x)^{-1} [ x [ L , L + d e g Q ) ] Q ( x ) − 1 相同.简单来说:递推关系(有理函数的分母)是不变的,我们所做的只是更换初值(有理函数的分子).
具体的,考虑
P ( x ) Q ( x ) = ∑ j ≥ 0 a j x j \frac{P(x)}{Q(x)}=\sum_{j\geq 0}a_jx^j Q ( x ) P ( x ) = j ≥ 0 ∑ a j x j
我们现在希望将递推前进 n n n 项,那么就是
∑ j ≥ n a j x j − n = P ( x ) Q ( x ) x n − Q ( x ) ∑ j = 0 n − 1 a j x j Q ( x ) x n \sum_{j\geq n}a_jx^{j-n}=\frac{P(x)}{Q(x)x^n}-\frac{Q(x)\sum_{j=0}^{n-1}a_jx^j}{Q(x)x^n} j ≥ n ∑ a j x j − n = Q ( x ) x n P ( x ) − Q ( x ) x n Q ( x ) ∑ j = 0 n − 1 a j x j
我们先用一次 Slice-Coefficients ( Q , L − deg P ) \operatorname{Slice-Coefficients}(Q,L-\deg{P}) Slice-Coefficients ( Q , L − deg P ) 计算出 [ x [ L − deg P , L − deg P + deg Q + 1 ) ] Q ( x ) − 1 \left\lbrack x^{\left\lbrack L-\deg{P},L-\deg{P}+\deg{Q}+1\right)}\right\rbrack Q(x)^{-1} [ x [ L − d e g P , L − d e g P + d e g Q + 1 ) ] Q ( x ) − 1 ,然后我们扩展合并出 [ x [ L − deg P , L + deg Q ) ] Q ( x ) − 1 \left\lbrack x^{\left\lbrack L-\deg{P},L+\deg{Q}\right)}\right\rbrack Q(x)^{-1} [ x [ L − d e g P , L + d e g Q ) ] Q ( x ) − 1 ,再重新计算一个分子使得
P ~ ( x ) Q ( x ) = ∑ j ≥ 0 ( [ x L + j ] P ( x ) Q ( x ) ) x j \frac{\widetilde{P}(x)}{Q(x)}=\sum_{j\geq 0}\left(\left\lbrack x^{L+j}\right\rbrack \frac{P(x)}{Q(x)}\right)x^j Q ( x ) P ( x ) = j ≥ 0 ∑ ( [ x L + j ] Q ( x ) P ( x ) ) x j
最后我们使用形式幂级数的除法计算出 [ x [ 0 , R − L ) ] P ~ ( x ) Q ( x ) \left\lbrack x^{\left\lbrack 0,R-L\right)}\right\rbrack\dfrac{\widetilde{P}(x)}{Q(x)} [ x [ 0 , R − L ) ] Q ( x ) P ( x ) ,时间为 O ( M ( d ) log L + M ( R − L ) ) O(\mathsf{M}(d)\log L+\mathsf{M}(R-L)) O ( M ( d ) log L + M ( R − L )) .
参考文献
Alin Bostan, Ryuhei Mori.A Simple and Fast Algorithm for Computing the N N N -th Term of a Linearly Recurrent Sequence .