字尾自動機

2021-09-25 14:48:02 字數 1416 閱讀 9844

基礎學習

簡潔明瞭的講解

總狀態數不超過2n−

12n-1

2n−1

(包括初始狀態)。

統計每個end

po

sendpos

endpos

等價類出現位置數量時,要按長度從長到短的計算cnt

cntcn

t。那為什麼一定要從長到短呢?(比如回文自動機就直接是按照節點編號從大到小計算cnt

cntcn

t)罪魁禍首就是複製得到的nqnq

nq,因為它的節點編號比較大,卻又要插入到節點編號比它小的q

qq的頭上(作為其父節點),這樣就導致若按節點編號計算cnt

cntcn

t,會導致某些節點入度還未減到0

00就開始更新它的父節點了。

將q

qq複製乙份得到nqnq

nq後,原先的q

qq就等效於被孤立了,用nqnq

nq去代替它的所有角色(初始的cnt

cntcn

t以及第一次的end

po

sendpos

endpos

值不能轉移給nqnq

nq,因為它們現在是父子關係)。

按長度排序時採用計數排序方便(用於得到第i短的狀態a[i

]a[i]

a[i]

)。遇到多組資料時別忘了初始化las

tlast

last

和s zsz

sz,都為111。

注意:源點(空串)下標為1

#include

"bits/stdc++.h"

#define hhh printf("hhh\n")

#define see(x) (cerr<<(#x)<<'='<<(x)namespace std;

typedef

long

long ll;

typedef pair<

int,

int> pr;

inline

intread()

const

int maxn =

5e5+10;

const

int mod =

1e9+7;

const

double eps =

1e-9

;char s[maxn]

;int ch[maxn*2]

[26], len[maxn*2]

, fa[maxn*2]

;int last=

1, tot=1;

void

add(

int c)}}

intmain()

字尾自動機

基礎知識 step i 表示的是字串i在原字串中的位置。pareint i 表示root到parent i 的子串是root到i的最長字尾。字尾自動機遍歷可以得到原字串的所有子串。特殊技巧 一 字尾自動機的不同子串數有兩種求法 1.ans step i step parent i 1 i cnt 2...

字尾自動機

常用於處理字串問題,可以高效解決許多字串問題。有點像將乙個字串的所有字尾都建在乙個ac自動機上,但不同的是字尾自動機的節點數最多為2 n,因為它只記錄需要記錄的點,一些沒有記錄東西的點可以視為與下面有價值的節點並在一起,這樣大大降低了時間複雜度和空間複雜度。對於每乙個節點記錄它的後面加上每個字元後字...

字尾自動機

include include includeusing namespace std const int n 1000000 10 char s n int len 2 n tr 2 n 32 link 2 n con 2,last 1 void add int c int main return ...