关于SAM和广义SAM

关于SAM和广义SAM

不是教程

某些思考先记下来

SAM

终于学会了这个东西诶......

一部分重要性质

确定一个重要事情,S构造出的SAM的一个重要性质是当且仅当对于S的任意一个后缀,可以从1号节点走到终止状态。专业的名词叫做有限状态自动机。

trans[st][c]表示的是对于状态st,如果将st中任意串s加一个c,那么会到达的新状态new,显然new是唯一的。假如不唯一那么s一定不属于同一个st。

fa[st]表示的是对于状态st,如果慢慢缩小st中后缀长度,会到达的第一个状态。规定一个虚点\(1\)全集,那么fa能够构成一个树形结构(parent tree)。

很显然\(endpos[st]\subset endpos[fa[st]]\)。所以虽然\(\sum|endpos|=O(n^2)\)但是可以通过线段树合并得到endpos集合。你也可以发现Parent Tree任何一个到根的链是一个长度递减且连续的某个后缀的前缀。

trans构成的有向图G一定是一个DAG,因为可以建立这个图从1到任意点的路径构成的串对应的原串,所以有环就出大事了。

G上任意一条从1开始走的路径都代表一个后缀的前缀——也就是一个子段。

而对于G任意一个i节点开始走的路径,表示的是对于后缀i的任意一个子段。

可以发现一个确定的Parent Tree和Trans[][]可以唯一确定一个串和SAM的形态。

构建和复杂度证明

先说构建,构建的目的是要让这个东西能够识别新的后缀并且还要维持好Parent Tree的各种性质。

设原来是S[1...r]现在我们要变成S[1...r+1],

首先可以发现的事情是,新状态一定包括\(S[1....r+1]\),设这个新状态为u,那么首先我们要让所有\(S[i...r+1]\)都被表示出来,我们可以一直跳\(v=r\)的fa,根据定义如果没有trans[v][c]我们要更新trans[v][S[r+1]]。然后一直跳如果直到1才停下来,说明之前\(S[(i \in[1,r])...r]\)都没出现过,那没事了。

但是如果到中间一个\(v\)而trans[v][c]=x,说明\(v\)代表的\(S[i...r+1]\)之前被表示出来过,按照parent tree的定义我们要更新enspos,

然后明天再更?

猜你喜欢

转载自www.cnblogs.com/winlere/p/12122139.html
SAM