Berlekamp-Massey算法,简称BM,用于寻找数列的最短递推式
给定数列,目标是找到递推式,满足对有
对一个递推式,要记第一次失败的位置,以及这个位置的偏差值
一开始令,遇到第一个的位置就令
接下来如果不满足,那么在之前的所有除外的递推式中找到最小的,令,那么新的满足的递推式就是,加号表示按位相加,容易验证这确实是递推式
找只需记录下来即可
xsy上的模板题
int a[10010];
struct tr{
int b[3010],k,f,d;
int&operator[](int k){return b[k];}
}fr,se,tmp;
int get(int i){
int j,s;
s=0;
for(j=1;j<=fr.k;j++)inc(s,mul(fr[j],a[i-j]));
return s;
}
int main(){
int n,i,j,d,t;
scanf("%d",&n);
for(i=1;i<=n;i++)scanf("%d",a+i);
for(i=1;i<=n;i++){
d=ad(a[i],mod-get(i));
if(!d)continue;
if(!fr.k){
fr.k=i;
se.f=i;
se.d=d;
continue;
}
t=mul(d,pow(se.d,mod-2));
tmp=fr;
tmp.k=max(fr.k,i-se.f+se.k);
inc(tmp[i-se.f],t);
for(j=1;j<=se.k;j++)inc(tmp[i-se.f+j],mod-mul(t,se[j]));
fr.f=i;
fr.d=d;
if(fr.k-fr.f<se.k-se.f)se=fr;
fr=tmp;
}
printf("%d\n",fr.k);
printf("%d",mod-1);
for(i=1;i<=fr.k;i++)printf(" %d",fr[i]);
}