引入

BM算法主要解决的是根据数列求最短线性齐次递推式的问题在OI中主要辅助打表使用

即:已知FFF,求序列AAA使得

Fn=∑i=1mAiFn−i(n>m)F_n=\sum_{i=1}^mA_iF_{n-i} \quad(n>m)Fn​=i=1∑m​Ai​Fn−i​(n>m)

其中mmm尽量小

算法流程

文中的所有序列下标均从111开始,并且为了方便规定000和负下标值均为000

该算法采用增量法,即我们求前nnn项的递推式,假设已经求出了前n−1n-1n−1项的递推式,我们记为AAA,考虑计算加上第nnn项后的递推式A′A'A′

设AAA的长度为mmm,也就是

m<k<n,Fk=∑i=1mAiFk−im<k<n,F_k=\sum_{i=1}^mA_iF_{k-i}m<k<n,Fk​=i=1∑m​Ai​Fk−i​

我们用现在不知道对不对的递推式,也就是上一个递推式AAA,算出FnF_nFn​不知道对不对的值,记为Fn′F'_nFn′​,也就是

Fn′=∑i=1mAiFn−iF'_n=\sum_{i=1}^mA_iF_{n-i}Fn′​=i=1∑m​Ai​Fn−i​

如果Fn=Fn′F_n=F'_nFn​=Fn′​,那么这个递推式暂时没有问题,继续往后,即A′=AA'=AA′=A

否则我们把这一位差了多少算出来,即

Δn=Fn−Fn′\Delta_n=F_n-F'_nΔn​=Fn​−Fn′​

注意有可能是负数

现在我们需要修正当前的递推式AAA

仔细观察这个递推式

k<n,∑i=1mAiFk−i=Fk∑i=1mAiFn−i=Fn−Δnk<n,\sum_{i=1}^mA_iF_{k-i}=F_k\\ \sum_{i=1}^{m}A_iF_{n-i}=F_n-\Delta_nk<n,i=1∑m​Ai​Fk−i​=Fk​i=1∑m​Ai​Fn−i​=Fn​−Δn​

和我们希望得到的递推式,这里设它长度为m′m'm′,显然有m′≥mm'\geq mm′≥m

k<n,∑i=1m′Ai′Fk−i=Fk∑i=1m′Ai′Fn−i=Fnk<n,\sum_{i=1}^{m'}A'_iF_{k-i}=F_k\\ \sum_{i=1}^{m'}A'_iF_{n-i}=F_nk<n,i=1∑m′​Ai′​Fk−i​=Fk​i=1∑m′​Ai′​Fn−i​=Fn​

我们可以考虑给AAA加上一个递推式DDD得到A′A'A′,容易知道它满足

k<n,∑i=1m′DiFk−i=0∑i=1m′DiFn−i=Δnk<n,\sum_{i=1}^{m'}D_iF_{k-i}=0\\ \sum_{i=1}^{m'}D_iF_{n-i}=\Delta_nk<n,i=1∑m′​Di​Fk−i​=0i=1∑m′​Di​Fn−i​=Δn​

现在尝试构造一个DDD

我们找到之前的一个匹配失败的递推式RRR,设它失败的位置为ppp,当时这个位置的差为Δp\Delta_pΔp​。为了避免标识太多看晕,我们还是把RRR的长度设为mmm,之后的mmm都是指RRR的长度

k<p,∑i=1mRiFk−i=Fk∑i=1mRiFp−i=Fk−Δpk<p,\sum_{i=1}^mR_iF_{k-i}=F_k\\ \sum_{i=1}^mR_iF_{p-i}=F_k-\Delta_pk<p,i=1∑m​Ri​Fk−i​=Fk​i=1∑m​Ri​Fp−i​=Fk​−Δp​

重新理一下这个式子的含义:

对当前位置k<pk<pk<p,我们从kkk往前面找mmm个数和RRR卷一下,然后用FkF_kFk​去减,都得到了000

唯独ppp不同,我们减出来得到了Δp\Delta_pΔp​

发现这个跟DDD神似

所以我们考虑这么构造DDD:

开始先放n−p−1n-p-1n−p−1个000进去,表示卷积的位置向左平移n−p−1n-p-1n−p−1位,实际上开始与D1D_1D1​对应相乘的位置是k−n+pk-n+pk−n+p,之后D2,D3,…,DmD_2,D_3,\dots,D_mD2​,D3​,…,Dm​的对应相乘位置不断向左挪

这时我们发现nnn恰好对应到了ppp,也就是RRR中唯一减出来不为000的位置

所以考虑构造这个减法 设x=ΔnΔpx={\Delta_n\over\Delta p}x=ΔpΔn​​

在n−pn-pn−p的位置放一个xxx

然后把RRR的每一位取−x-x−x倍接在后面

这样不考虑xxx的话,nnn对应的卷出来是FpF_pFp​减去用RRR算出来的Fp′F'_pFp′​,即Δp\Delta_pΔp​,乘上xxx得到Δn\Delta_nΔn​。其他位置因为Fk=Fk′F_k=F'_kFk​=Fk′​,所以卷出来是000。

也就是

D={0,0,…,0⏟n-p-1个0,x,−xR1,−xR2,…,−xRn}D=\{ \underbrace{0,0,\dots,0}_\text{n-p-1个0},x,-xR_1,-xR_2,\dots,-xR_n \}D={n-p-1个00,0,…,0​​,x,−xR1​,−xR2​,…,−xRn​}

可(bu)以(yong)证明,选取最近的RRR一定是最优的

把AAA加上DDD就可以得到A′A'A′

复杂度O(n2)O(n^2)O(n2)

模板题

道理我都懂,为啥好好的BM模板要加个线性递推

注:此代码只有BM部分

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#define MAXN 10005
using namespace std;
inline int read()
{int ans=0;char c=getchar();while (!isdigit(c)) c=getchar();while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();return ans;
}
const int MOD=998244353;
inline int add(const int& x,const int& y){return x+y>=MOD? x+y-MOD:x+y;}
inline int dec(const int& x,const int& y){return x<y? x-y+MOD:x-y;}
typedef long long ll;
inline int qpow(int a,int p)
{int ans=1;while (p){if (p&1) ans=(ll)ans*a%MOD;a=(ll)a*a%MOD;p>>=1;}return ans;
}
int F[MAXN],R[MAXN];
int las[MAXN],tmp[MAXN],p,delta;
int main()
{int n,m;n=read(),m=read();for (int i=1;i<=n;i++) F[i]=read();for (int i=1;i<=n;i++){int res=0;for (int j=1;j<=R[0];j++) res=add(res,(ll)R[j]*F[i-j]%MOD);if (res==F[i]) continue;if (!R[0]){p=i;delta=F[i];R[0]=i;continue;}memcpy(tmp,R,sizeof(tmp));int x=(ll)dec(F[i],res)*qpow(delta,MOD-2)%MOD;R[i-p]=add(R[i-p],x);for (int j=1;j<=las[0];j++) R[i-p+j]=dec(R[i-p+j],(ll)x*las[j]%MOD);R[0]=i+las[0]-p;memcpy(las,tmp,sizeof(las));p=i,delta=dec(F[i],res);}for (int i=1;i<=R[0];i++) printf("%d%c",R[i]," \n"[i==R[0]]);return 0;
}

感性理解Berlekamp-Massey算法相关推荐

  1. Berlekamp–Massey算法简要介绍

    这是一篇翻译向的文章,笔者整理了一些有关Berlekamp–Massey算法的笔记,还增加了一些自己的理解. 下面列出了笔者写此文时所参考的一些资料: wikipedia fjzzq2002 别人的博 ...

  2. Berlekamp–Massey 算法

    学习博客 学习博客 BM算法用于求解常系数线性递推式. 它可以在 O(n2)O(n^2)O(n2) 的时间复杂度内解决问题. 先打个比赛,一会再更 学习算法看上边的两个学习链接就行,板子可以参考我下边 ...

  3. Berlekamp Massey算法(HDU6172)

    用途:常系数k阶递推式求值 HDU6172 #include <bits/stdc++.h>using namespace std; #define rep(i, a, n) for (l ...

  4. 理解最大期望算法EM的三层境界(1)

    Expectation Maximization(EM) 不要强求不可知,要从已知推未知 在刚开始学习时,我觉得EM算法真的难,反反复复就是看不懂.我一开始找到的学习资料上来就是一大堆算法公式推导.我 ...

  5. 看图轻松理解数据结构与算法系列(合并排序)

    前言 推出一个新系列,<看图轻松理解数据结构和算法>,主要使用图片来描述常见的数据结构和算法,轻松阅读并理解掌握.本系列包括各种堆.各种队列.各种列表.各种树.各种图.各种排序等等几十篇的 ...

  6. RAFT 寻找一种易于理解的一致性算法(扩展版)

    摘要 Raft 是一种为了管理复制日志的一致性算法.它提供了和 Paxos 算法相同的功能和性能,但是它的算法结构和 Paxos 不同,使得 Raft 算法更加容易理解并且更容易构建实际的系统.为了提 ...

  7. 5分钟带你理解一致性Hash算法

    转载自 5分钟带你理解一致性Hash算法 一致性Hash算法背景 一致性哈希算法在1997年由麻省理工学院的Karger等人在解决分布式Cache中提出的,设计目标是为了解决因特网中的热点(Hot s ...

  8. EM算法的九层境界:​Hinton和Jordan理解的EM算法

    导读 知乎上有一个讨论:EM算法存在的意义是什么?是什么原因使得EM算法这么流行呢?EM算法是Hinton和Jordan强强发力的领域,本文作者纵向解析EM算法的9层境界,深入浅出,值得一读. Hin ...

  9. 深度学习之感性理解-机器学习基础一

    深度学习之感性理解-机器学习基础一 机器学习是什么 机器学习用来干嘛的 机器学习是怎么做的 机器学习是什么 关于机器学习的定义,网上很多,我就不多说了,谈谈自己的理解.简单的说就是有一个事情想让计算机 ...

  10. 100天搞定机器学习|day37 无公式理解反向传播算法之精髓

     100天搞定机器学习(Day1-34) 100天搞定机器学习|Day35 深度学习之神经网络的结构 100天搞定机器学习|Day36 深度学习之梯度下降算法 本篇为100天搞定机器学习之第37天,亦 ...

最新文章

  1. 远程计算机串口控制软件,智能控制的设备上使用远程开关需要用到RS485串口继电器、网关、电脑平台...
  2. 取代C语言的标准输入输出:cin 和 cout【C++标准输入输出】
  3. Hybris (SAP旗下的软件公司)
  4. android onclick事件和ontouch事件发生先后顺序和关联
  5. CD marker 是什么?
  6. 六、Excel中重要的数据透视表,必须要学会
  7. springboot工厂模式_最新整理138道阿里、快手等大厂面试题解析:基础+Spring+并发+JVM+设计模式+缓存...
  8. Android笔记 - android 类型转化错误
  9. java int和String类型之间的相互转换
  10. (89)FPGA写文件激励(fdisplay)
  11. 【Python配置】Win10配置Python3、Numpy、PyCharm、Anaconda
  12. DeepMind为明年的AAAI,准备了一份各种DQN的混血
  13. 关于jquery获取单选框value属性值为on的问题
  14. dism 分割镜像_2019系统教程,如何拆分WIM镜像里面多余的子映像、控制体积-映像文件怎么打开...
  15. Java基础面试题(持续更新)
  16. vue绑定背景图片有括号无法显示怎么办
  17. python视频笔记17(控制窗体)
  18. 班级校园网页设计作业 静态HTML我的班级网页 DW班级网站模板下载 大学生简单班级网页作品代码 我的大学网页制作 学生班级网页设计作业
  19. 关于0x80070091 目录不是空的
  20. 关于C语言输出ASCII码128~255和有符号char型溢出的问题。此处大坑弄明白了后记录下来分享……

热门文章

  1. vue 日期格式化返回指定个数月份_vue过滤器实现日期格式化的案例分析
  2. 这些高校竟因名字太“坑爹”被误会为三本?盘点九所实力强劲但被名字耽误的大学...
  3. 只要懂得拒绝,哪会有什么狗血感情与莫名其妙的误会
  4. 吃货都是怎么给自己找理由的? | 今日最佳
  5. 有效处理 Java 异常三原则
  6. word2013插入excel对象报错_在Word文档中修改嵌入的Excel对象
  7. 命中率_数据说话!詹姆斯的“皇家射手团”命中率为近十年最低
  8. abb限位开关已打开drv1_广告雕刻机限位开关触发
  9. 只能选择分卷文件的第一部分。_为机器学习模型选择正确的度量评估(第一部分)...
  10. jpa 根据主键生成策略获取id_如何在使用JPA和Hibernate时选择id生成策略