【SPOJ - LCS2】Longest Common Substring II【SAM】
题意
求出多个串的最长公共子串。
分析
刚学SAM想做这个题的话最好先去做一下那道codevs3160。求两个串的LCS应该怎么求?把一个串s1建自动机,然后跑另一个串s2,然后找出s2每个前缀的最长公共后缀。那么多个的时候,我们也用这种类似的方法,但是我们求最长公共后缀的时候要求第一个串的。我们把其中一个串建SAM,然后把其他的串都在上面跑,维护两个值,Max[u]和Min[u]。自动机中每个状态u的Right存的是结尾集合。那么对于一个字符串,我们可以求出他和自动机中每个状态的最长公共后缀。然后,我们通过Max[fa[u]]=max(Max[fa[u]],Max[u])来确定左右状态的最长公共后缀,然后更新Min[o]。
下面的代码没有AC,但是我找了好久BUG没找到··如果有人看完并且找到了bug麻烦跟我说一下万分感谢!
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std;
const int maxn=+;
char s[maxn];
struct state{
int len,link;
int next[];
}st[*maxn];
int n,last,cur,sz;
int Min[*maxn],Max[*maxn],c[*maxn]; void init(){
sz=;
cur=last=;
st[].link=-;
st[].len=;
} void build_sam(int c){
cur=sz++;
st[cur].len=st[last].len+;
Min[cur]=st[cur].len;
int p;
for(p=last;p!=-&&st[p].next[c]==;p=st[p].link)
st[p].next[c]=cur;
if(p==-)
st[cur].link=;
else{
int q=st[p].next[c];
if(st[q].len==st[p].len+)
st[cur].link=q;
else{
int clone=sz++;
st[clone].len=st[p].len+;
Min[clone]=st[clone].len;
st[clone].link=st[q].link;
for(int i=;i<;i++)
st[clone].next[i]=st[q].next[i];
for(;p!=-&&st[p].next[c]==q;p=st[p].link)
st[p].next[c]=clone;
st[cur].link=st[q].link=clone;
}
}
last=cur;
} int cmp(int a,int b){
return st[a].len<st[b].len;
} int main(){
scanf("%s",s);
n=strlen(s);
init(); for(int i=;i<n;i++)
build_sam(s[i]-'a');
for(int i=;i<sz;i++)
c[i]=i;
sort(c,c+sz,cmp); while(scanf("%s",s)!=EOF){
n=strlen(s);
int u=,len=;
for(int i=;i<n;i++){
int c=s[i]-'a';
if(u!=-&&st[u].next[c]==)
u=st[u].link,len=st[u].len;
if(u==-)
u=,len=;
else{
u=st[u].next[c];
len++;
Max[u]=max(Max[u],len);
}
} for(int i=sz-;i>=;i--){
int o=c[i];
Min[o]=min(Min[o],Max[o]);
if(st[o].link!=-){
Max[st[o].link]=max(Max[st[o].link],Max[o]);
}
Max[o]=;
}
}
int ans=;
for(int i=;i<sz;i++){
ans=max(ans,Min[i]);
}
printf("%d\n",ans); return ;
}
【SPOJ - LCS2】Longest Common Substring II【SAM】的更多相关文章
- 【SPOJ】Longest Common Substring II (后缀自动机)
[SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记 ...
- 【SPOJ】Longest Common Substring II
[SPOJ]Longest Common Substring II 多个字符串求最长公共子串 还是将一个子串建SAM,其他字符串全部跑一边,记录每个点的最大贡献 由于是所有串,要对每个点每个字符串跑完 ...
- SPOJ1812 LCS2 - Longest Common Substring II【SAM LCS】
LCS2 - Longest Common Substring II 多个字符串找最长公共子串 以其中一个串建\(SAM\),然后用其他串一个个去匹配,每次的匹配方式和两个串找\(LCS\)一样,就是 ...
- 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, \(\ ...
- 【spoj LCS2】 Longest Common Substring II
http://www.spoj.com/problems/LCS2/ (题目链接) 题意 求多个串的最长公共子串 Solution 对其中一个串构造后缀自动机,然后其它串在上面跑匹配.对于每个串都可以 ...
- SPOJ LCS2 - Longest Common Substring II 字符串 SAM
原文链接http://www.cnblogs.com/zhouzhendong/p/8982484.html 题目传送门 - SPOJ LCS2 题意 求若干$(若干<10)$个字符串的最长公共 ...
- 【SPOJ 1812】Longest Common Substring II
http://www.spoj.com/problems/LCS2/ 这道题想了好久. 做法是对第一个串建后缀自动机,然后用后面的串去匹配它,并在走过的状态上记录走到这个状态时的最长距离.每匹配完一个 ...
- 【SP1812】LCS2 - Longest Common Substring II
[SP1812]LCS2 - Longest Common Substring II 题面 洛谷 题解 你首先得会做这题. 然后就其实就很简单了, 你在每一个状态\(i\)打一个标记\(f[i]\)表 ...
- 【SPOJ】Longest Common Substring(后缀自动机)
[SPOJ]Longest Common Substring(后缀自动机) 题面 Vjudge 题意:求两个串的最长公共子串 题解 \(SA\)的做法很简单 不再赘述 对于一个串构建\(SAM\) 另 ...
随机推荐
- ibernate+Struts2环境如何使用jqGrid。
因为公司项目需要,在Hibernate+Struts2的环境下,研究了一下如何使用jqGrid. 说实在的,Struts2+jqGrid不是一个很好的组合.因为jqGrid中很多功能,基本上都使用的是 ...
- kotlin与fastjson的异常
出现这个原因是因为kotlin的非空特性. 如果一个类中声明了一个字段(kotlin的特性,该字段默认是非空的), 使用fastjson进行转化的时候,如果json数据中没有该字段的数据,则会出现转换 ...
- NetCore 下集成SignalR并进行分组处理
Tips: 1.注意跟普通版Net.MVC的前端处理方式不一样,以前可以connection.start()后直接done里面再做逻辑处理,现在不行了 建议做法是在具体的业务Hub里重写OnConne ...
- Warning: skipping non-radio button in group. 的处理
1)把你的第一个Radio选中group属性: 2)把你“这个组中”的最后一个Raido控件“后”的一个控件(指得是控件添加先后的顺序,可以用ctrl+d来修改顺序)也选中group属性,如最后一个R ...
- 【UVa】11212 Editing a Book(IDA*)
题目 题目 分析 get一下IDA*的技巧,感觉总体来说不难,主要是剪枝比较难想. 这是lrj的代码,比较通俗易懂,关键就是选定一个区间再取出来,插入到一个位置,接下来转移到这个状态. ...
- c++ 双向链表操作总结
第一.包含DoubleLinkNode 模板类和DoubleLinkList 模板类 #pragma once #include<iostream> using namespace std ...
- 跟我一起学kafka(一)
从昨天下午接到新任务,要采集一个法院网站得所有公告,大概是需要采集这个网站得所有公告列表里得所有txt内容,txt文件里边是一件件赤裸裸得案件,记录这案由,原告被告等相关属性(不知道该叫什么就称之为属 ...
- FrameworkElement.FindName 根据名字查找控件
WPF FrameworkElement.FindName 根据名字查找控件 运行环境:Window7 64bit,NetFramework4.7,C# 7.0, 编者:乌龙哈里 2017-10 ...
- Make 命令教程(转载)
代码变成可执行文件,叫做编译(compile):先编译这个,还是先编译那个(即编译的安排),叫做构建(build). Make是最常用的构建工具,诞生于1977年,主要用于C语言的项目.但是实际上 , ...
- MyBatis初识(通过小实例清晰认识MyBatis)
1.MyBatis框架: MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可 ...