后缀自动机(SAM)模板
struct SAM{
int ch[maxn][],fa[maxn],len[maxn],cnt,last;
void Init()
{
memset(ch,,sizeof(ch));
memset(fa,,sizeof(fa));
last=cnt=;
}
void Add(int c)
{
int p=last,np=last=++cnt;
len[np]=len[p]+;
while(!ch[p][c]&&p){
ch[p][c]=np;p=fa[p];
}
if(p==)
fa[np]=;
else{
int q=ch[p][c];
if(len[p]==len[q]-){
fa[np]=q;
}
else{
int nq=++cnt;len[nq]=len[p]+;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];fa[q]=fa[np]=nq;
while(ch[p][c]==q&&p){
ch[p][c]=nq;
p=fa[p];
}
}
}
}
};
然后是自整理最全SAM模版,超级大杀器!
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int N=;
char s[N];
int fa[N],pos[N],vis[N],sa[N],rank[N];
int son[N][],end[N],rht[N],lcp[N];
int ch[N][],len[N],id[N],tot;
int od[N],wv[N],lst,cnt; void Init(){
memset(ch,,sizeof(ch));
memset(end,,sizeof(end));
memset(son,,sizeof(son));
memset(vis,,sizeof(vis));
lst=cnt=;tot=;
} void Insert(int c){
int p=lst,np=lst=++cnt;end[lst]=;
id[len[np]=len[p]+]=np;rht[np]=;
while(p&&!ch[p][c])ch[p][c]=np,p=fa[p];
if(!p)fa[np]=;
else{
int q=ch[p][c],nq;
if(len[q]==len[p]+)fa[np]=q;
else{
len[nq=++cnt]=len[p]+;
fa[nq]=fa[q];fa[q]=fa[np]=nq;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
while(ch[p][c]==q)ch[p][c]=nq,p=fa[p];
}
}
} void Get_Right(){
for(int i=;i<=cnt;i++)wv[len[i]]++;
for(int i=;i<=cnt;i++)wv[i]+=wv[i-];
for(int i=;i<=cnt;i++)od[wv[len[i]]--]=i;
for(int i=cnt;i>=;i--)rht[fa[od[i]]]+=rht[od[i]];
} void Build_Tree(){
int l=strlen(s+);
for(int i=l;i>=;i--)Insert(s[i]-'a');
for(int i=l;i>=;i--)
for(int x=id[i],p=l+;x&&!pos[x];x=fa[x])
p-=len[x]-len[fa[x]],pos[x]=p;
for(int x=;x<=cnt;x++)son[fa[x]][s[pos[x]]-'a']=x;
} void DFS(int x,int l){
if(end[x])sa[rank[l-len[x]+]=++tot]=l-len[x]+;
for(int i=;i<;i++)if(son[x][i])DFS(son[x][i],l);
} void Build_SA(){
int l=strlen(s+),k=;DFS(,l);
for(int i=,j;i<=l;lcp[rank[i++]]=k)
for(k?k--:k,j=sa[rank[i]-];s[i+k]==s[j+k];k++);
} int main(){
//freopen();
//freopen();
Init();
scanf("%s",s+);
int l=strlen(s+);
Build_Tree();Build_SA();
for(int i=;i<=l;i++)printf("%d ",sa[i]);printf("\n");
for(int i=;i<=l;i++)printf("%d ",lcp[i]);printf("\n");
return ;
}
警告:这里的SAM都是naive-sam,无法跑trie和多串。
后缀自动机(SAM)模板的更多相关文章
- SPOJ 1811. Longest Common Substring (LCS,两个字符串的最长公共子串, 后缀自动机SAM)
1811. Longest Common Substring Problem code: LCS A string is finite sequence of characters over a no ...
- 浅谈后缀自动机SAM
一下是蒟蒻的个人想法,并不很严谨,仅供参考,如有缺误,敬请提出 参考资料: 陈立杰原版课件 litble 某大神 某大神 其实课件讲得最详实了 有限状态自动机 我们要学后缀自动机,我们先来了解一下自动 ...
- 后缀自动机(SAM)奶妈式教程
后缀自动机(SAM) 为了方便,我们做出如下约定: "后缀自动机" (Suffix Automaton) 在后文中简称为 SAM . 记 \(|S|\) 为字符串 \(S\) 的长 ...
- [转]后缀自动机(SAM)
原文地址:http://blog.sina.com.cn/s/blog_8fcd775901019mi4.html 感觉自己看这个终于觉得能看懂了!也能感受到后缀自动机究竟是一种怎样进行的数据结构了. ...
- 【算法】后缀自动机(SAM) 初探
[自动机] 有限状态自动机的功能是识别字符串,自动机A能识别字符串S,就记为$A(S)$=true,否则$A(S)$=false. 自动机由$alpha$(字符集),$state$(状态集合),$in ...
- 后缀自动机SAM学习笔记
前言(2019.1.6) 已经是二周目了呢... 之前还是有一些东西没有理解到位 重新写一下吧 后缀自动机的一些基本概念 参考资料和例子 from hihocoder DZYO神仙翻译的神仙论文 简而 ...
- 【算法】后缀自动机(SAM) 例题
算法介绍见:http://www.cnblogs.com/Sakits/p/8232402.html 广义SAM资料:https://www.cnblogs.com/phile/p/4511571.h ...
- 后缀自动机(SAM) 学习笔记
最近学了SAM已经SAM的比较简单的应用,SAM确实不好理解呀,记录一下. 这里提一下后缀自动机比较重要的性质: 1,SAM的点数和边数都是O(n)级别的,但是空间开两倍. 2,SAM每个结点代表一个 ...
- 后缀自动机SAM
某神犇:"初三还不会后缀自动机,那就退役吧!" 听到这句话后,我的内心是崩溃的. 我还年轻,我还不想退役--于是,我在后来,努力地学习后缀自动机. 终于,赶在初三开学前,我终于学会 ...
随机推荐
- asp.net 的状态管理
状态管理 (state management) 在Web应用程序中,一向是很重要的课题,良好的状态管理可以帮助开发人员发展出具有状态持续能力的应用程序(像是工作流程型应用程序或是电子商务应用程序),但 ...
- js数组操作的常用方法
数组:arr=[1,2,3,4,5]; 1.数组转换成字符串,不会修改原数组内容: arr.join(); // "1,2,3,4,5" arr.join("" ...
- Member var and Static var.
/* member variable and static variable: 1,invoke ways: member variable,also called 'instance' variab ...
- OpenWrt启动过程分析
openwrt是通过一系列shell脚本进行启动流程的组织,下面是启动流程的提纲.如 果想详细了解启动的过程,则需要仔细走读脚本文件. 1. 在make menuconfig 选择target平台 B ...
- 在C语言中使用scanf语句时遇到的问题总结
在使用visual studio2013编写c语言代码时,遇到了这样的几个小问题,进行如下的总结. 1, 关于使用scanf语句报错的解决方案1 #include <stdio.h> in ...
- 【cogs858】磁性链
[题目描述] 有N块编号为1~N的特殊磁石相互吸附组成一条磁性链,只有它们紧挨着时才会传递吸力,他们之间的吸力很大,如果我们要从N块相连的磁石中取出一块,那么需要消耗N-1个单位的能量,空缺处不再有吸 ...
- Centos7搭建php+mysql环境(整理篇)
终于将mysql+php环境搭建成功,将之前的整理一下,环境:centos7,本机IP:192.168.1.24,数据库用户名及密码都设为root,测试文件路径:/var/www/html 1.取消c ...
- ios开发之IBOutlet和IBAction的区别
IBOutlet 输出口是使用关键字IBOutlet声明的实例变量.控制器头文件中的输出口声明应如下所示: @property (nonatomic, retain) IBOutlet UIButto ...
- pojo和JavaBean的区别
javabean可以处理业务,pojo不可以. pojo就是get 和set 例如: Student{ id; name; get();... set();...} javabean可以实现业务逻辑 ...
- Android 内核基本知识
Android基本知识 Android基本知识.... 1 1. 各版本系统特性.... 1 2. View绘制流程.... 2 3. 动画体系.... 2 4. 事件分发机制.... 3 输入消息获 ...