字尾自動機 SAM 學習筆記

2021-09-29 10:39:52 字數 2691 閱讀 4994

參考資料

hihocoder1441

hihocoder1445

史上最通俗的字尾自動機詳解

練習題hihocoder1449

hihocoder1457

hihocoder1465

hihocoder1413 筆記

字串 aab

模板

struct suffixautomaton

int q=ch[p]

[c];

if(len[p]+1

==len[q]

)int nq=

++cnt;

memcpy

(ch[nq]

,ch[q]

,sizeof ch[q]);

len[nq]

=len[p]+1

; fa[nq]

=fa[q]

; fa[q]

=fa[np]

=nq;

for(

;ch[p]

[c]==q;p=fa[p]

) ch[p]

[c]=nq;

}//t==0表示相同子串不重複計算,t==1表示重複計算

void

work()}};

dag上dp

確定遍歷順序,陣列 a 為結點遍歷順序

for

(int i=

1;i<=node;i++

) t[len[i]]++

;for

(int i=

1;i<=node;i++

) t[i]

+=t[i-1]

;for

(int i=

1;i<=node;i++

) a[t[len[i]]--

]=i;

乙個結點出發的不同子串個數

對於乙個節點 i

ii,f[i

]f[i]

f[i]

表示從 i

ii 出發的子串個數(不含空串)。那麼, f[i

]f[i]

f[i]

就等於∑(i

,j)∈

edge

(f[j

]+1)

\sum_(f[j]+1)

∑(i,j)

∈edg

e​(f

[j]+

1),f [1

]f[1]

f[1]

即是答案。

轉移順序的話,就按照 a

aa 的倒序

for

(int i=cnt;i>=

1;i--

)for

(int j=

0;j<

26;j++)if

(ch[a[i]

][j]

) f[a[i]]+

=f[ch[a[i]

][j]]+

1;

乙個子串出現的次數等於其所在狀態的 end

posendpos

endpos

的大小

size[np]=1

;for

(int i=cnt;i;i--

) size[fa[a[i]]]

+=size[a[i]

];

乙個狀態所包含的子串的數量
for

(int i=

1;i<=cnt;i++

)for

(int j=

0;j<

26;j++)if

(ch[a[i]

][j]

) num[ch[a[i]

][j]]+

=num[a[i]

];

最長公共字首
int u=

廣義字尾自動機

struct sam 

else

else

}return np;

}void

init()

void

build()

}for

(int i=

1;i<=cnt;i++

)for

(int i=

1;i<=cnt;i++

)for

(int i=

1;i<=cnt;i++

)for

(int i=cnt;i>root;i--

) size[fa[a[i]]]

+= size[a[i]];}};

學習筆記 字尾自動機SAM

好抽象啊,早上看了兩個多小時才看懂,fading 早就懂了 講解就算了吧 可以去看看其他人的部落格 siz 為該串出現的次數,l 為子串長度,每次乘一下就好了 code below include define ll long long using namespace std const int m...

字尾自動機SAM

原理詳細的可以看史上最通俗的字尾自動機詳解 想看懂還是要花很久。實現 include include using namespace std const int maxn 2000010 struct node nodes maxn int las 1 tot 1 char st maxn void...

SAM 字尾自動機

好文 luogup3804 定義.對給定字串s的字尾自動機是乙個最小化確定有限狀態自動機,它能夠接收字串s的所有字尾。對給定字串s的字尾自動機是乙個最小化確定有限狀態自動機,它能夠接收字串s的所有字尾。某一狀態t 0被稱作初始狀態,由它能夠到達其餘所有狀態。自動機中的所有轉移 即有向邊 都被某種符號...