首页 > 编程语言 >Berlekamp-Massey 算法(求数列的最短递推式)

Berlekamp-Massey 算法(求数列的最短递推式)

时间:2022-10-31 08:35:03浏览次数:66  
标签:Massey cnt int lst Berlekamp Delta fail 递推

用于求数列的最短递推式。

本文参考自 https://www.cnblogs.com/jz-597/p/14983564.html

增量法,设 \(R_i\) 表示第 \(i\) 个历史递推式,当前为 \(R_{cnt}\)。

设 \(\Delta\) 表示真实的 \(a_i\) 与用 \(R_{cnt}\) 求出的 \(a_i\) 的差值,即 \(\Delta=a_i-\sum_{j=1}^{|R_{cnt}|}a_{i-j}R_{cnt,j}\)。

  • 若 \(\Delta=0\),则无事发生,跳过。
  • 若 \(\Delta\neq 0\),那么我们需要调整这个递推式使得它对 \(a_i\) 也成立。

接下来看第二种情况怎么处理。

有一个想法是找到另一个递推式,使得这个递推式在算 \(\cdots,a_{i-1}\) 时取 \(0\),在算 \(a_i\) 时取 \(\Delta\)。

我们可以找到一个历史递推式 \(R_{lst}\),设其失配位置为 \(fail_{lst}\),失配时的差值为 \(\Delta_{lst}\)(显然 \(\Delta_{lst}\neq 0\))。

设 \(d=\dfrac{\Delta}{\Delta_{lst}}\),那么我们可以找到这么一个递推式 \(R'=\{0,0,\cdots,0,d,-d\cdot R_{lst,1},-d\cdot R_{lst,2},\cdots\}\),其中前面是 \(i-fail_{lst}-1\) 个 \(0\)。

可以发现,使用这个递推式得到的 \(a_i'=\sum_{j=1}^{|R'|}R'_{j}a_{i-j}=d(a_{fail_{lst}}-\sum_{j=1}^{|R_{lst}|}R_{lst,j}a_{fail_{lst}-j})=d\cdot \Delta_{lst}=\Delta\)。

而对于任意 \((i-k)\in [|R'|+1,i-1]\),\(a_{i-k}'=\sum_{j=1}^{|R'|}R'_j{a_{(i-k)-j}}=d(a_{fail_{lst}-k}-\sum_{j=1}^{|R_{lst}|}R_{lst,j}a_{(fail_{lst}-k)-j})=0\)。

那么我们令 \(R_{cnt+1}\gets R_{cnt}+R'\) 即可。

实质上是利用了以前的信息 \(R_{lst}\):注意到失配前的差值都是 \(0\),所以我们用差值来定义递推式。

那么我们怎么找到最短的 \(R'\) 呢?由于 \(|R'|=i+\big(|R_{lst}|-fail_{lst}\big)\),所以我们直接找 \(|R_{lst}|-fail_{lst}\) 最小的就好了。

至于为什么求出来的递推式一定是最短的不会证。

【XSY3403】求数列的最短递推式 代码:

#include<bits/stdc++.h>

#define N 10010

using namespace std;

namespace modular
{
    const int mod=1000000007;
    inline int add(int x,int y){return x+y>=mod?x+y-mod:x+y;}
    inline int dec(int x,int y){return x-y<0?x-y+mod:x-y;}
    inline int mul(int x,int y){return 1ll*x*y%mod;}
    inline void Add(int &x,int y){x=x+y>=mod?x+y-mod:x+y;}
}using namespace modular;

inline int poww(int a,int b)
{
    int ans=1;
    while(b)
    {
        if(b&1) ans=mul(ans,a);
        a=mul(a,a);
        b>>=1;
    }
    return ans;
}

inline int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9')
    {
        if(ch=='-') f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9')
    {
        x=(x<<1)+(x<<3)+(ch^'0');
        ch=getchar();
    }
    return x*f;
}

int n,a[N],delta[N],fail[N];

vector<int>r[N];

int main()
{
    n=read();
    for(int i=1;i<=n;i++) a[i]=read();
    int cnt=0,lst=cnt;
    for(int i=1;i<=n;i++)
    {
        delta[cnt]=0;
        for(int j=0;j<r[cnt].size();j++)
            Add(delta[cnt],mul(r[cnt][j],a[i-j-1]));
        delta[cnt]=dec(a[i],delta[cnt]);
        if(!delta[cnt]) continue;
        fail[cnt]=i;
        if(!cnt)
        {
            r[++cnt].resize(i);
            continue;
        }
        r[cnt+1]=r[cnt];
        r[cnt+1].resize(max((int)r[cnt+1].size(),i+(int)r[lst].size()-fail[lst]));
        int d=mul(delta[cnt],poww(delta[lst],mod-2));
        Add(r[cnt+1][i-fail[lst]-1],d);
        for(int j=0;j<r[lst].size();j++)
            Add(r[cnt+1][i-fail[lst]+j],mul(dec(0,d),r[lst][j]));
        if((int)r[cnt].size()-fail[cnt]<(int)r[lst].size()-fail[lst]) lst=cnt;
        cnt++;
    }
    printf("%d\n1000000006 ",(int)r[cnt].size());
    for(int i=0;i<r[cnt].size();i++)
        cout<<r[cnt][i]<<" \0"[i==r[cnt].size()-1];
    return 0;
}

标签:Massey,cnt,int,lst,Berlekamp,Delta,fail,递推
From: https://www.cnblogs.com/ez-lcw/p/16843023.html

相关文章

  • 【atcoder 293 E - Sugoroku 4】【动态规划,递推】
    importjava.io.IOException;importjava.util.Arrays;importjava.util.Scanner;publicclassMain{staticintn,m,k;staticintMOD=998244353;......
  • 拯救LongMM (递推公式求解)
    拯救LongMM(lan.pas/c/cpp)【题目描述】LongDD将军为了平息延续数年战乱,决定释放战俘营中所有的俘虏。然而,LongDD将军不......
  • CF 254E(从当前向后递推)
    E.宿舍分享timelimitpertestmemorylimitpertestinputoutputn 天.第i天......
  • AcWing 算法提高课 通过递推求等比数列的和(防止使用逆元出现问题)
    基于分治的思想:  例题:https://www.acwing.com/problem/content/99/模板:求num^0+num^1+...+num^kconstintMOD=9901;intQuickExp(intbase,intexp){bas......
  • 辛普生公式和龙贝格递推的实现
    如题,数值分析编程作业 代码:#include<iostream>#include<string>#include<cstring>#include<cmath>#include<stack>#include<queue>#include<map>#include<vect......
  • 费解的开关[二进制、递推]
    题面传送门[https://www.acwing.com/problem/content/description/97/]分析考虑逐行分析,以行递推如果不再改变第一行,则满足题意的点击方案最多1种理由是:如果第i行某一......
  • 现代功率谱估计(2):Levinson-Durbin递推方法求解AR模型参数
    现代功率谱估计(2):Levinson-Durbin递推方法求解AR模型参数p阶AR模型的差分方程形式和系统函数分别为:令\(z=e^{jw}\),则AR模型输出的功率谱密度为:AR模型的系统输出信号......
  • 递推
    递推百度之星递推题(用矩阵乘法加速,用费马小定理缩小)思路:因为只有1->0的情况是0,其他都是1,所以我们考虑递推。$f[n]=2^n-f[n-1]\(,\)2^n$是所有情况,因此唯一可......
  • 矩阵递推斐波那契数列
      斐波那契数列都很熟悉,它满足,\(F_{n}=\begin{cases}1&n\leqslant2\\F_{n-1}+F_{n-2}&n>2\end{cases}\)。因为\(F_n\)从第三项开始是不断的递推下去的,所以......
  • 划分数列(ybtoj递推练习题1)
    题目描述给定一个长度为n的数列 ,要求划分最少的段数,使得每一段要么单调不降,要么单调不升。输入格式第一行一个整数 。接下来n个数表示数列 。......