SAM:后缀自动机
好文转载
luoguP3804
代码:
/*
定义.对给定字符串s的后缀自动机是一个最小化确定有限状态自动机,它能够接收字符串s的所有后缀。
对给定字符串s的后缀自动机是一个最小化确定有限状态自动机,它能够接收字符串s的所有后缀。
某一状态t_0被称作初始状态,由它能够到达其余所有状态。
自动机中的所有转移——即有向边——都被某种符号标记。从某一状态出发的诸转移必须拥有不同的标记。(另一方面,状态转移不能在任何字符上)。
一个或多个状态被标记为终止状态。如果我们从初始状态t_0经由任意路径走到某一终止状态,并顺序写出所有经过边的标记,你得到的字符串必然是s的某一后缀。
在符合上述诸条件的所有自动机中,后缀自动机有这最少的顶点数。(后缀自动机并不被要求拥有最少的边数) 最简性:它包含了所有s的子串的信息。换言之,对于任意从初始状态t_0出发的路径,如果我们写出所经过边上的标记,形成的子串必须是s的子串。相应地,s的任意子串都对应一条从初始状态t_0出发的路径。
为了简化说明,我们称子串“匹配”了从初始状态出发的路径,如果该路径上的边标记组成了这一子串。相应地,我们称任意路径“匹配”某一子串,该子串由路径中边的标记组成。
后缀自动机的每个状态都引领一条或多条从初始状态出发的路径。我们称这个状态有若干匹配这些路径的方法。 引理1.两个非空子串u和v(length(u)<=length(v))是终点等价的,当且仅当u在字符串s中仅作为w的后缀出现。
引理2.考虑两个非空子集u,w(length(u)<=length(w))。它们的终点集合不相交,或者endpos(w)是endpos(u)的子集。进一步地,这取决于u是否是w的后缀:
引理3.考虑一个终点等价类。将该等价类中的子串按长度递减排序。排序后的序列中,每个子串将比上一个子串短,从而是上一个字串的后缀。换句话说,某一终点等价类中的字符串互为后缀,它们的长度依次取区间[x,y]内的所有数。
引理4.后缀链接组成了一棵以t_0为根的树。
引理5.如果我们将所有合法的终点集合建成一棵树(使得孩子是父母的子集),这棵树将和后缀链接构成的树相同。 状态的数量:
由长度为n的字符串s建立的后缀自动机的状态个数不超过2n-1(对于n>=3)。
转移的数量:
由长度为n的字符串s建立的后缀自动机中,转移的数量不超过3n-4(对于n>=3)。 定理1.DAWG(s)中后缀链接组成的树就是后缀树ST(rev(s))。
定理2.图DAWG(s)的边都能用后缀树ST(rev(s))的扩展指针表示。另外,DAWG(s)中的连续转移就是ST(rev(s))中反向的后缀指针。
定理3.使用后缀自动机DAWG(s),我们可以用O(n)的时间构建后缀树ST(rev(s))。
定理4.使用后缀树ST(rev(s)),我们可以用O(n)的时间构建后缀自动机DAWG(s)。 */
#include <cstdio>
#include <complex>
#include <cstring>
#ifdef Win32
#define LL "%I64d"
#else
#define LL "%lld"
#endif
const int N=2e6+;
typedef long long ll;
char s[N];
int a[N],c[N],size[N],n;
ll ans=;
inline int max(int x,int y)
{return x>y?x:y;}
struct SuffixAutoMaton
{
int last,cnt,ch[N<<][],fa[N<<],l[N<<];
void ins(int c)
{
int p=last,np=++cnt;
last=np;l[np]=l[p]+;
for(;p&&!ch[p][c];p=fa[p])
ch[p][c]=np;
if(!p)fa[np]=;
else
{
int q=ch[p][c];
if(l[p]+==l[q])
fa[np]=q;
else
{
int nq=++cnt;
l[nq]=l[p]+;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];
fa[q]=fa[np]=nq;
for(;ch[p][c]==q;p=fa[p])
ch[p][c]=nq;
}
}
size[np]=;
}
void build()
{
scanf("%s",s+);
int len=strlen(s+);
last=cnt=;
for(int i=;i<=len;++i)
ins(s[i]-'a');
}
void calc()
{
for(int i=;i<=cnt;++i)++c[l[i]];
for(int i=;i<=cnt;++i)c[i]+=c[i-];
for(int i=;i<=cnt;++i)a[c[l[i]]--]=i;
for(int i=cnt;i;--i)
{
int p=a[i];
size[fa[p]]+=size[p];
if(size[p]>)
ans=max(ans,1LL*size[p]*l[p]);
}
printf(LL "\n",ans);
}
}sam;
int main()
{
sam.build();
sam.calc();
return ;
}
SAM:后缀自动机的更多相关文章
- Distinct Substrings(spoj694)(sam(后缀自动机)||sa(后缀数组))
Given a string, we need to find the total number of its distinct substrings. Input \(T-\) number of ...
- 弦论(tjoi2015,bzoj3998)(sam(后缀自动机))
对于一个给定长度为\(N\)的字符串,求它的第\(K\)小子串是什么. Input 第一行是一个仅由小写英文字母构成的字符串\(S\) 第二行为两个整数\(T\)和\(K\),\(T\)为0则表示不同 ...
- LCS2 - Longest Common Substring II(spoj1812)(sam(后缀自动机)+多串LCS)
A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\ ...
- LCS - Longest Common Substring(spoj1811) (sam(后缀自动机)+LCS)
A string is finite sequence of characters over a non-empty finite set \(\sum\). In this problem, \(\ ...
- Lexicographical Substring Search (spoj7259) (sam(后缀自动机)+第k小子串)
Little Daniel loves to play with strings! He always finds different ways to have fun with strings! K ...
- Substrings(SPOJ8222) (sam(后缀自动机))
You are given a string \(S\) which consists of 250000 lowercase latin letters at most. We define \(F ...
- sam(后缀自动机)
后缀自动机ins解释 void ins(int c){ int p=last;//将当前节点的parent节点变为last int np=++cnt;//建立新节点 last=np;//将last设为 ...
- Luogu P3346 [ZJOI2015]诸神眷顾的幻想乡 广义SAM 后缀自动机
题目链接 \(Click\) \(Here\) 真的是好题啊-不过在说做法之前先强调几个自己总是掉的坑点. 更新节点永远记不住往上跳\(p = fa[p]\) 新建节点永远记不住\(len[y] = ...
- 字符串(tjoi2016,heoi2016,bzoj4556)(sam(后缀自动机)+线段树合并+倍增+二分答案)
佳媛姐姐过生日的时候,她的小伙伴从某东上买了一个生日礼物.生日礼物放在一个神奇的箱子中.箱子外边写了 一个长为\(n\)的字符串\(s\),和\(m\)个问题.佳媛姐姐必须正确回答这\(m\)个问题, ...
- 后缀自动机SAM学习笔记
前言(2019.1.6) 已经是二周目了呢... 之前还是有一些东西没有理解到位 重新写一下吧 后缀自动机的一些基本概念 参考资料和例子 from hihocoder DZYO神仙翻译的神仙论文 简而 ...
随机推荐
- Build step 'Send files or execute commands over SSH' changed build result to UNSTABLE
删除logs文件夹日志即可
- Centos 6.10 安装 Jenkins
前言 持续集成的概念 持续集成,Continuous integration ,简称CI. 持续集成正是针对这一类问题的一种软件开发实践.它倡导团队开发成员必须经常集成他们的工作,甚至每天都可能发生多 ...
- CCF 2016-04-2 俄罗斯方块
CCF 2016-04-2 俄罗斯方块 题目 问题描述 俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游戏. 游戏在一个15行10列的方格图上进行,方格图上的每一个格子可能已经放置了方块,或者 ...
- Excel默认去除开头的0
用户反映打开的.xls文档打开时,excel会默认把某些以0开头零件号去零,导致数据丢失. 解决办法: 先用记事本打开,然后把EXCEL的单元格格式设为文本格式,再把数据复制过去就可以了. 或者先打开 ...
- adb server is out of date. killing... ADB server didn't ACK * failed to start daemon *……
问题 使用 adb 命令的时候报错如下: adb server is out of date. killing... ADB server didn't ACK * failed to start d ...
- Bootstrap框架 简单使用
目录 Bootstrap框架 简单使用 什么是Bootstrap 下载 Bootstrap 项目结构 Bootstrap 简单使用 表格格式 Bootstrap 按钮颜色 尺寸 Bootstrap框架 ...
- C# 将Excel导出PDF
1.安装所需包,使用nuget安装所需包 1.1.Spire.Xls 1.2.iTextSharp.text.pdf 2.Spire.Xls介绍 将Excel转换为PDF是一个很常用的功能,常见的转换 ...
- sqlite移植
编译 # tar xvf sqlite-3.6.16.tar.gz # cd sqlite-3.6.16 # ./configure # ./configure --host=arm-linux -- ...
- MySQL Binlog--PURGE MASTER LOGS失败
问题背景: 在我们磁盘空间维护策略中,BINLOG的默认保留期限为7天,但当磁盘空间不足时,会根据磁盘空间使用率自动清理超过一定数量的BINLOG. 问题原因: 某服务器上报磁盘空间不足,登录服务器发 ...
- Computer Vision_33_SIFT:Fast Adaptive Bilateral Filtering——2018
此部分是计算机视觉部分,主要侧重在底层特征提取,视频分析,跟踪,目标检测和识别方面等方面.对于自己不太熟悉的领域比如摄像机标定和立体视觉,仅仅列出上google上引用次数比较多的文献.有一些刚刚出版的 ...