日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

感性理解Berlekamp-Massey算法

發(fā)布時間:2023/12/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 感性理解Berlekamp-Massey算法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

引入

BM算法主要解決的是根據(jù)數(shù)列求最短線性齊次遞推式的問題在OI中主要輔助打表使用

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

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

其中mmm盡量小

算法流程

文中的所有序列下標均從111開始,并且為了方便規(guī)定000和負下標值均為000

該算法采用增量法,即我們求前nnn項的遞推式,假設(shè)已經(jīng)求出了前n?1n-1n?1項的遞推式,我們記為AAA,考慮計算加上第nnn項后的遞推式A′A'A

設(shè)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=1m?Ai?Fk?i?

我們用現(xiàn)在不知道對不對的遞推式,也就是上一個遞推式AAA,算出FnF_nFn?不知道對不對的值,記為Fn′F'_nFn?,也就是

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

如果Fn=Fn′F_n=F'_nFn?=Fn?,那么這個遞推式暫時沒有問題,繼續(xù)往后,即A′=AA'=AA=A

否則我們把這一位差了多少算出來,即

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

注意有可能是負數(shù)

現(xiàn)在我們需要修正當前的遞推式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=1m?Ai?Fk?i?=Fk?i=1m?Ai?Fn?i?=Fn??Δn?

和我們希望得到的遞推式,這里設(shè)它長度為m′m'm,顯然有m′≥mm'\geq mmm

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=1m?Ai?Fk?i?=Fk?i=1m?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=1m?Di?Fk?i?=0i=1m?Di?Fn?i?=Δn?

現(xiàn)在嘗試構(gòu)造一個DDD

我們找到之前的一個匹配失敗的遞推式RRR,設(shè)它失敗的位置為ppp,當時這個位置的差為Δp\Delta_pΔp?。為了避免標識太多看暈,我們還是把RRR的長度設(shè)為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=1m?Ri?Fk?i?=Fk?i=1m?Ri?Fp?i?=Fk??Δp?

重新理一下這個式子的含義:

對當前位置k<pk<pk<p,我們從kkk往前面找mmm個數(shù)和RRR卷一下,然后用FkF_kFk?去減,都得到了000

唯獨ppp不同,我們減出來得到了Δp\Delta_pΔp?

發(fā)現(xiàn)這個跟DDD神似

所以我們考慮這么構(gòu)造DDD:

開始先放n?p?1n-p-1n?p?1000進去,表示卷積的位置向左平移n?p?1n-p-1n?p?1位,實際上開始與D1D_1D1?對應(yīng)相乘的位置是k?n+pk-n+pk?n+p,之后D2,D3,…,DmD_2,D_3,\dots,D_mD2?,D3?,,Dm?的對應(yīng)相乘位置不斷向左挪

這時我們發(fā)現(xiàn)nnn恰好對應(yīng)到了ppp,也就是RRR中唯一減出來不為000的位置

所以考慮構(gòu)造這個減法 設(shè)x=ΔnΔpx={\Delta_n\over\Delta p}x=ΔpΔn??

n?pn-pn?p的位置放一個xxx

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

這樣不考慮xxx的話,nnn對應(yīng)的卷出來是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-100,0,,0??,x,?xR1?,?xR2?,,?xRn?}

可(bu)以(yong)證明,選取最近的RRR一定是最優(yōu)的

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

復(fù)雜度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; }

總結(jié)

以上是生活随笔為你收集整理的感性理解Berlekamp-Massey算法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。