首页 技术 正文

SAM

技术 2022年11月10日
0 收藏 301 点赞 3,396 浏览 1648 个字

后缀自动机能识别字符串S的所有子串,是一个DAG。

http://blog.csdn.net/huanghongxun/article/details/51112764

https://blog.xehoth.cc/SuffixAutomation/

hihocoder上的一堆SAM入门教程挺友好的。

附SAM模板

 const int N = 1e6+;
struct SAM{
//pre[]: parent树, pre[i]是i的后缀, 字符串长度小于i
//son[][]: trans DAG图
//ml[]: maxlen, min[i] = max[pre[i]]+1, 不同的字符串个数是maxlen-minlen+1
int tot, last, pre[N<<], son[N<<][], ml[N<<];
void init() {
tot = , last = ;
memset(son[], , sizeof son[]);
}
void extend(char c){
int w = c-'a', p = ++tot, x = last, r, q;
memset(son[p], , sizeof son[p]);
for(ml[last = p] = ml[x]+; x&&!son[x][w]; x = pre[x]) son[x][w] = p;
if(!x) pre[p] = ;
else if(ml[x]+ == ml[q = son[x][w]]) pre[p] = q;
else{
pre[r = ++tot] = pre[q];
memcpy(son[r], son[q], sizeof son[r]);
ml[r] = ml[x]+;
pre[p] = pre[q] = r;
for(; x&&son[x][w] == q; x = pre[x]) son[x][w] = r;
}
}
};

结点:

后缀自动机的节点表示一类不同的子串,它们在原串中出现的位置的Ri全部相同。(Right集合相同)

节点的属性就是1. Right集   2.长度区间[min(s), max(s)] (表示该节点表示的子串的长度范围)。

边:

边分两类,转移边与parent边。

转移边就是读入下一个字符后跳转的结点。故转移过去的节点对应的字符串集合至少包含原节点的字符串集添加字符。

parent边就是fail边,每次经fail边跳转后,max(fa(s))=min(s)−1,一个节点及其父节点的代表的串有相同的后缀

沿trans图前行,节点对应的字符串集合变大;

沿parent树回溯,节点对应字符串长度区间[minlen, maxlen] -> [?, minlen-1],right集合变大

节点对应的不同子串数 = maxlen-minlen+1 (所有不同子串数 = 各节点求和 = 从root出发的可行路径条数(dp) )

节点对应的字符串在原串中出现的次数 = 节点对应的right集合大小 = trans图中节点走到终点态的方案数 = parent树中子树在主链上的节点数

循环同构字符串处理技巧: 构造s0…sn-1s0…sn-2

如何求s, t的最长公共子串?

构造出s的SAM,用t在SAM上跑,维护当前匹配的最长长度len,

读入一个字符,

若沿trans图有对应边,则len = len+1;

否则沿parent树回溯,则len = maxlen

然后要理解后缀自动机的节点数不超过2n−1(n≥3), 转移数不超过3n−3条。

(转移数想的时间比较久。首先因为只有n个后缀,故出度为0的点不超过n个。那么假设只有2n-2条边,构成一棵生成树,那么每再加入一条边a -> b,我们都能有一条root -> a – > b -> end的路径,表示某一后缀。

root -> a, b -> end都是生成树上的边。那么加入的边不会超过n个就能构造出所有后缀。经过从具体请戳第一个链接)

=======================================================================================

应用:http://blog.csdn.net/huanghongxun/article/details/51112764

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,498
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,911
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,745
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,499
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:8,138
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:5,302