Berlekamp-Massey算法
设 (R) 表示数列 ({a_1,a_2,cdots,a_n}) 的最短线性递推式 ({r_1,r_2,cdots,r_m}) ,即
用Berlekamp-Massey算法可以在 (O(n |R|)) 的时间算出 (R) .
可以用于找到题目性质,乃至于直接求出答案的递推式.
算法思想
求出 ({a_1,a_2,cdots,a_{i-1}}) 的最短线性递推式,然后通过调整的方法求出 ({a_1,a_2,cdots,a_i,a_i}) 的最短线性递推式
算法流程
定义 ({a_1,a_2,cdots,a_{i-1}}) 的最短线性递推式 ({r_1,r_2,cdots,r_m}) 为当前递推式,记递推式修改此时为 (cnt) ,第 (i) 次修改后的递推式为 (R_i) ,则当前递推式为 (R_{cnt}) .
初始 (R_{0}={}) 为空.
设 (d_i = a_i - sum_{j=1}^{m} a_{i-j}r_j) .若 (d_i=0) 则不需要修改当前递推式.
否则,记 (fail_{cnt}=i) 表示出错位置.
若 (cnt=0) ,那么可以令 (R_1={underbrace{0,0,cdots,0}_{i ext{ zeros}}}) ,因为当前数列长度为 (i) ,所以这是合法的.
否则,考虑求出 (R'={r'_1,r'_2,cdots,r'_{m'}}) 使得
那么我们就可以令 (R_{cnt+1} = R_{cnt} + R') 了.
考虑构造 (R') ,设 (M= dfrac {d_i}{d_{fail_{cnt-1}}}) . 那么令 (R'={underbrace{0,0,cdots,0}_{i-fail_{cnt-1}-1 ext{ zeros}},M} +(-M cdot R_{cnt-1})) 其中 (+) 表示两个数列拼起来, (cdot) 表示数列中的每个数乘上某个数.
考虑这样是否满足上述条件,有 (m'=i-fail_{cnt-1}+|R_{cnt-1}|)
因为 (k-(i-fail_{cnt-1}) < fail_{cnt-1}) ,所以上式成立.
综上,我们构造的 (R') 是合法的.
一次修改的复杂度为 (O(|R|)) ,一共要进行 (O(n)) 次修改,复杂度为 (O(n |R|)) .