问题模型
给定一个有\(n\)个元素的数列\(a\),其中第\(i\)个元素是\(a_i\)。
求一个较短或者最短的数列\(b\),假设\(b\)有\(m\)个元素,那么要求满足
\(\forall m <i\leq n,a_i = \sum_{j = 1}^m a_{i - j} b_j\)
要求\(O(n^2)\)时间内解决此问题。
BM算法
考虑增量法。
设递推式经过了\(c\)次更新,第\(i\)次的更新后的递推式为\(R_i\),定义\(R_0\)全空。
考虑在当且数列末尾加上 \(a_i\),假设当前递推式长度为\(m\)。
设\(delta_i = a_i - \sum_{j = 1}^m a_{i - j}R_{c,j}\)
如果\(delta_i = 0\)则不需要修改。
否则设\(F_c = i\)表示\(R_c\)第一次失效的位置。
当前插入\(i\),考虑构造一个递推式:似的\(\forall k,|R'| + 1 \leq k < i\),\(\sum_j a_{k - j}R'_j = 0\),\(\sum_j a_{i - j}R'_j = delta_i\)
考虑\(0\leq id < c\),设\(tmp = \frac{delta_i}{delta_{{F}_{id}}}\)
\(R' = {0,0,0,0,0,tmp,-tmp*R_{id,1},-tmp*R_{id,2}...}\)
(有\(i - F_{id} - 1\))个0.
令\(R_{c+1} = R_c + R'\)即可。
考虑选择最短的\(i - F_{id} - 1 + len(F_{id})\)即可。