BM算法总结

BM算法,可以求一个数列的最短递推式。
采用增量法,依次考虑每个数:
若在这个位置上正确,则忽略;
否则,类似拉格朗日插值法,找一个满足在前面位置都为0,这个位置上不为0的递推式,进行修补。
每当我们遇到一个这样的位置时,我们都可以得到一个这样的递推式:用目前的递推式,在0位置(即这个位置上),增加一个-1。相当于积累了一个“经验”。
这样,我们在所有的“经验”中,找到一个,并在它的前面补0,相当于移位。
若有多个,取补0后长度最小的。
时间复杂度:\(O(n(n+m))\)。(n为递推式长度,m为输入长度)。
代码:

int BM(int sz[10010],int n)
{
    int m=0;
    for(int i=1;i<=n;i++)
    {
        cd[i]=inf;
        int he=(md-sz[i])%md;
        for(int j=1;j<=m;j++)
            he=(he+1ll*ans[j]*sz[i-j])%md;
        if(he==0)
            continue;
        int ny=ksm(he,md-2);
        sb[i][0]=(md-ny)%md;
        for(int j=1;j<=m;j++)
            sb[i][j]=1ll*ans[j]*ny%md;
        cd[i]=m;int mi=inf,wz;
        for(int j=0;j<i;j++)
        {
            int t=cd[j]+(i-j);
            if(t<=mi)
                mi=t,wz=j;
        }
        for(int j=0;j<=cd[wz];j++)
            ans[i-wz+j]=(ans[i-wz+j]-1ll*sb[wz][j]*he%md+md)%md;
        if(mi>m)m=mi;
    }
    return m;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章